/**
 * Copyright (c) 2021 OceanBase
 * OceanBase Database Proxy(ODP) is licensed under Mulan PubL v2.
 * You can use this software according to the terms and conditions of the Mulan PubL v2.
 * You may obtain a copy of Mulan PubL v2 at:
 *          http://license.coscl.org.cn/MulanPubL-2.0
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PubL v2 for more details.
 */

#include "lib/charset/ob_ctype.h"
#include "lib/charset/ob_dtoa.h"
#include "lib/charset/ob_uctype.h"
#include "lib/utility/ob_macro_utils.h"

#define IS_CONTINUATION_BYTE(c) (((c) ^ 0x80) < 0x40)

static unsigned char ctype_utf8mb4[]=
{
  0x00,  0x20,  0x20,  0x20,  0x20,  0x20,  0x20,  0x20,
  0x20,  0x20,  0x28,  0x28,  0x28,  0x28,  0x28,  0x20,
  0x20,  0x20,  0x20,  0x20,  0x20,  0x20,  0x20,  0x20,
  0x20,  0x20,  0x20,  0x20,  0x20,  0x20,  0x20,  0x20,
  0x20,  0x48,  0x10,  0x10,  0x10,  0x10,  0x10,  0x10,
  0x10,  0x10,  0x10,  0x10,  0x10,  0x10,  0x10,  0x10,
  0x10,  0x84,  0x84,  0x84,  0x84,  0x84,  0x84,  0x84,
  0x84,  0x84,  0x84,  0x10,  0x10,  0x10,  0x10,  0x10,
  0x10,  0x10,  0x81,  0x81,  0x81,  0x81,  0x81,  0x81,
  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,
  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,
  0x01,  0x01,  0x01,  0x01,  0x10,  0x10,  0x10,  0x10,
  0x10,  0x10,  0x82,  0x82,  0x82,  0x82,  0x82,  0x82,
  0x02,  0x02,  0x02,  0x02,  0x02,  0x02,  0x02,  0x02,
  0x02,  0x02,  0x02,  0x02,  0x02,  0x02,  0x02,  0x02,
  0x02,  0x02,  0x02,  0x02,  0x10,  0x10,  0x10,  0x10,
  0x20,  0x03,  0x03,  0x03,  0x03,  0x03,  0x03,  0x03,
  0x03,  0x03,  0x03,  0x03,  0x03,  0x03,  0x03,  0x03,
  0x03,  0x03,  0x03,  0x03,  0x03,  0x03,  0x03,  0x03,
  0x03,  0x03,  0x03,  0x03,  0x03,  0x03,  0x03,  0x03,
  0x03,  0x03,  0x03,  0x03,  0x03,  0x03,  0x03,  0x03,
  0x03,  0x03,  0x03,  0x03,  0x03,  0x03,  0x03,  0x03,
  0x03,  0x03,  0x03,  0x03,  0x03,  0x03,  0x03,  0x03,
  0x03,  0x03,  0x03,  0x03,  0x03,  0x03,  0x03,  0x03,
  0x03,  0x03,  0x03,  0x03,  0x03,  0x03,  0x03,  0x03,
  0x03,  0x03,  0x03,  0x03,  0x03,  0x03,  0x03,  0x03,
  0x03,  0x03,  0x03,  0x03,  0x03,  0x03,  0x03,  0x03,
  0x03,  0x03,  0x03,  0x03,  0x03,  0x03,  0x03,  0x03,
  0x03,  0x03,  0x03,  0x03,  0x03,  0x03,  0x03,  0x03,
  0x03,  0x03,  0x03,  0x03,  0x03,  0x03,  0x03,  0x03,
  0x03,  0x03,  0x03,  0x03,  0x03,  0x03,  0x03,  0x03,
  0x03,  0x03,  0x03,  0x03,  0x03,  0x03,  0x03,  0x03
};


static unsigned char to_lower_utf8mb4[]=
{
  0x00,  0x01,  0x02,  0x03,  0x04,  0x05,  0x06,  0x07,
  0x08,  0x09,  0x0a,  0x0b,  0x0c,  0x0d,  0x0e,  0x0f,
  0x10,  0x11,  0x12,  0x13,  0x14,  0x15,  0x16,  0x17,
  0x18,  0x19,  0x1a,  0x1b,  0x1c,  0x1d,  0x1e,  0x1f,
  0x20,  0x21,  0x22,  0x23,  0x24,  0x25,  0x26,  0x27,
  0x28,  0x29,  0x2a,  0x2b,  0x2c,  0x2d,  0x2e,  0x2f,
  0x30,  0x31,  0x32,  0x33,  0x34,  0x35,  0x36,  0x37,
  0x38,  0x39,  0x3a,  0x3b,  0x3c,  0x3d,  0x3e,  0x3f,
  0x40,  0x61,  0x62,  0x63,  0x64,  0x65,  0x66,  0x67,
  0x68,  0x69,  0x6a,  0x6b,  0x6c,  0x6d,  0x6e,  0x6f,
  0x70,  0x71,  0x72,  0x73,  0x74,  0x75,  0x76,  0x77,
  0x78,  0x79,  0x7a,  0x5b,  0x5c,  0x5d,  0x5e,  0x5f,
  0x60,  0x61,  0x62,  0x63,  0x64,  0x65,  0x66,  0x67,
  0x68,  0x69,  0x6a,  0x6b,  0x6c,  0x6d,  0x6e,  0x6f,
  0x70,  0x71,  0x72,  0x73,  0x74,  0x75,  0x76,  0x77,
  0x78,  0x79,  0x7a,  0x7b,  0x7c,  0x7d,  0x7e,  0x7f,
  0x80,  0x81,  0x82,  0x83,  0x84,  0x85,  0x86,  0x87,
  0x88,  0x89,  0x8a,  0x8b,  0x8c,  0x8d,  0x8e,  0x8f,
  0x90,  0x91,  0x92,  0x93,  0x94,  0x95,  0x96,  0x97,
  0x98,  0x99,  0x9a,  0x9b,  0x9c,  0x9d,  0x9e,  0x9f,
  0xa0,  0xa1,  0xa2,  0xa3,  0xa4,  0xa5,  0xa6,  0xa7,
  0xa8,  0xa9,  0xaa,  0xab,  0xac,  0xad,  0xae,  0xaf,
  0xb0,  0xb1,  0xb2,  0xb3,  0xb4,  0xb5,  0xb6,  0xb7,
  0xb8,  0xb9,  0xba,  0xbb,  0xbc,  0xbd,  0xbe,  0xbf,
  0xc0,  0xc1,  0xc2,  0xc3,  0xc4,  0xc5,  0xc6,  0xc7,
  0xc8,  0xc9,  0xca,  0xcb,  0xcc,  0xcd,  0xce,  0xcf,
  0xd0,  0xd1,  0xd2,  0xd3,  0xd4,  0xd5,  0xd6,  0xd7,
  0xd8,  0xd9,  0xda,  0xdb,  0xdc,  0xdd,  0xde,  0xdf,
  0xe0,  0xe1,  0xe2,  0xe3,  0xe4,  0xe5,  0xe6,  0xe7,
  0xe8,  0xe9,  0xea,  0xeb,  0xec,  0xed,  0xee,  0xef,
  0xf0,  0xf1,  0xf2,  0xf3,  0xf4,  0xf5,  0xf6,  0xf7,
  0xf8,  0xf9,  0xfa,  0xfb,  0xfc,  0xfd,  0xfe,  0xff
};


static unsigned char to_upper_utf8mb4[]=
{
  0x00,  0x01,  0x02,  0x03,  0x04,  0x05,  0x06,  0x07,
  0x08,  0x09,  0x0a,  0x0b,  0x0c,  0x0d,  0x0e,  0x0f,
  0x10,  0x11,  0x12,  0x13,  0x14,  0x15,  0x16,  0x17,
  0x18,  0x19,  0x1a,  0x1b,  0x1c,  0x1d,  0x1e,  0x1f,
  0x20,  0x21,  0x22,  0x23,  0x24,  0x25,  0x26,  0x27,
  0x28,  0x29,  0x2a,  0x2b,  0x2c,  0x2d,  0x2e,  0x2f,
  0x30,  0x31,  0x32,  0x33,  0x34,  0x35,  0x36,  0x37,
  0x38,  0x39,  0x3a,  0x3b,  0x3c,  0x3d,  0x3e,  0x3f,
  0x40,  0x41,  0x42,  0x43,  0x44,  0x45,  0x46,  0x47,
  0x48,  0x49,  0x4a,  0x4b,  0x4c,  0x4d,  0x4e,  0x4f,
  0x50,  0x51,  0x52,  0x53,  0x54,  0x55,  0x56,  0x57,
  0x58,  0x59,  0x5a,  0x5b,  0x5c,  0x5d,  0x5e,  0x5f,
  0x60,  0x41,  0x42,  0x43,  0x44,  0x45,  0x46,  0x47,
  0x48,  0x49,  0x4a,  0x4b,  0x4c,  0x4d,  0x4e,  0x4f,
  0x50,  0x51,  0x52,  0x53,  0x54,  0x55,  0x56,  0x57,
  0x58,  0x59,  0x5a,  0x7b,  0x7c,  0x7d,  0x7e,  0x7f,
  0x80,  0x81,  0x82,  0x83,  0x84,  0x85,  0x86,  0x87,
  0x88,  0x89,  0x8a,  0x8b,  0x8c,  0x8d,  0x8e,  0x8f,
  0x90,  0x91,  0x92,  0x93,  0x94,  0x95,  0x96,  0x97,
  0x98,  0x99,  0x9a,  0x9b,  0x9c,  0x9d,  0x9e,  0x9f,
  0xa0,  0xa1,  0xa2,  0xa3,  0xa4,  0xa5,  0xa6,  0xa7,
  0xa8,  0xa9,  0xaa,  0xab,  0xac,  0xad,  0xae,  0xaf,
  0xb0,  0xb1,  0xb2,  0xb3,  0xb4,  0xb5,  0xb6,  0xb7,
  0xb8,  0xb9,  0xba,  0xbb,  0xbc,  0xbd,  0xbe,  0xbf,
  0xc0,  0xc1,  0xc2,  0xc3,  0xc4,  0xc5,  0xc6,  0xc7,
  0xc8,  0xc9,  0xca,  0xcb,  0xcc,  0xcd,  0xce,  0xcf,
  0xd0,  0xd1,  0xd2,  0xd3,  0xd4,  0xd5,  0xd6,  0xd7,
  0xd8,  0xd9,  0xda,  0xdb,  0xdc,  0xdd,  0xde,  0xdf,
  0xe0,  0xe1,  0xe2,  0xe3,  0xe4,  0xe5,  0xe6,  0xe7,
  0xe8,  0xe9,  0xea,  0xeb,  0xec,  0xed,  0xee,  0xef,
  0xf0,  0xf1,  0xf2,  0xf3,  0xf4,  0xf5,  0xf6,  0xf7,
  0xf8,  0xf9,  0xfa,  0xfb,  0xfc,  0xfd,  0xfe,  0xff
};


static uint32_t lower00[]={
  0x0000,  0x0001,  0x0002,  0x0003,  0x0004,  0x0005,  0x0006,  0x0007,
  0x0008,  0x0009,  0x000A,  0x000B,  0x000C,  0x000D,  0x000E,  0x000F,
  0x0010,  0x0011,  0x0012,  0x0013,  0x0014,  0x0015,  0x0016,  0x0017,
  0x0018,  0x0019,  0x001A,  0x001B,  0x001C,  0x001D,  0x001E,  0x001F,
  0x0020,  0x0021,  0x0022,  0x0023,  0x0024,  0x0025,  0x0026,  0x0027,
  0x0028,  0x0029,  0x002A,  0x002B,  0x002C,  0x002D,  0x002E,  0x002F,
  0x0030,  0x0031,  0x0032,  0x0033,  0x0034,  0x0035,  0x0036,  0x0037,
  0x0038,  0x0039,  0x003A,  0x003B,  0x003C,  0x003D,  0x003E,  0x003F,
  0x0040,  0x0061,  0x0062,  0x0063,  0x0064,  0x0065,  0x0066,  0x0067,
  0x0068,  0x0069,  0x006A,  0x006B,  0x006C,  0x006D,  0x006E,  0x006F,
  0x0070,  0x0071,  0x0072,  0x0073,  0x0074,  0x0075,  0x0076,  0x0077,
  0x0078,  0x0079,  0x007A,  0x005B,  0x005C,  0x005D,  0x005E,  0x005F,
  0x0060,  0x0061,  0x0062,  0x0063,  0x0064,  0x0065,  0x0066,  0x0067,
  0x0068,  0x0069,  0x006A,  0x006B,  0x006C,  0x006D,  0x006E,  0x006F,
  0x0070,  0x0071,  0x0072,  0x0073,  0x0074,  0x0075,  0x0076,  0x0077,
  0x0078,  0x0079,  0x007A,  0x007B,  0x007C,  0x007D,  0x007E,  0x007F,
  0x0080,  0x0081,  0x0082,  0x0083,  0x0084,  0x0085,  0x0086,  0x0087,
  0x0088,  0x0089,  0x008A,  0x008B,  0x008C,  0x008D,  0x008E,  0x008F,
  0x0090,  0x0091,  0x0092,  0x0093,  0x0094,  0x0095,  0x0096,  0x0097,
  0x0098,  0x0099,  0x009A,  0x009B,  0x009C,  0x009D,  0x009E,  0x009F,
  0x00A0,  0x00A1,  0x00A2,  0x00A3,  0x00A4,  0x00A5,  0x00A6,  0x00A7,
  0x00A8,  0x00A9,  0x00AA,  0x00AB,  0x00AC,  0x00AD,  0x00AE,  0x00AF,
  0x00B0,  0x00B1,  0x00B2,  0x00B3,  0x00B4,  0x00B5,  0x00B6,  0x00B7,
  0x00B8,  0x00B9,  0x00BA,  0x00BB,  0x00BC,  0x00BD,  0x00BE,  0x00BF,
  0x00E0,  0x00E1,  0x00E2,  0x00E3,  0x00E4,  0x00E5,  0x00E6,  0x00E7,
  0x00E8,  0x00E9,  0x00EA,  0x00EB,  0x00EC,  0x00ED,  0x00EE,  0x00EF,
  0x00F0,  0x00F1,  0x00F2,  0x00F3,  0x00F4,  0x00F5,  0x00F6,  0x00D7,
  0x00F8,  0x00F9,  0x00FA,  0x00FB,  0x00FC,  0x00FD,  0x00FE,  0x00DF,
  0x00E0,  0x00E1,  0x00E2,  0x00E3,  0x00E4,  0x00E5,  0x00E6,  0x00E7,
  0x00E8,  0x00E9,  0x00EA,  0x00EB,  0x00EC,  0x00ED,  0x00EE,  0x00EF,
  0x00F0,  0x00F1,  0x00F2,  0x00F3,  0x00F4,  0x00F5,  0x00F6,  0x00F7,
  0x00F8,  0x00F9,  0x00FA,  0x00FB,  0x00FC,  0x00FD,  0x00FE,  0x00FF,
};

static uint32_t upper00[]={
  0x0000,  0x0001,  0x0002,  0x0003,  0x0004,  0x0005,  0x0006,  0x0007,
  0x0008,  0x0009,  0x000A,  0x000B,  0x000C,  0x000D,  0x000E,  0x000F,
  0x0010,  0x0011,  0x0012,  0x0013,  0x0014,  0x0015,  0x0016,  0x0017,
  0x0018,  0x0019,  0x001A,  0x001B,  0x001C,  0x001D,  0x001E,  0x001F,
  0x0020,  0x0021,  0x0022,  0x0023,  0x0024,  0x0025,  0x0026,  0x0027,
  0x0028,  0x0029,  0x002A,  0x002B,  0x002C,  0x002D,  0x002E,  0x002F,
  0x0030,  0x0031,  0x0032,  0x0033,  0x0034,  0x0035,  0x0036,  0x0037,
  0x0038,  0x0039,  0x003A,  0x003B,  0x003C,  0x003D,  0x003E,  0x003F,
  0x0040,  0x0041,  0x0042,  0x0043,  0x0044,  0x0045,  0x0046,  0x0047,
  0x0048,  0x0049,  0x004A,  0x004B,  0x004C,  0x004D,  0x004E,  0x004F,
  0x0050,  0x0051,  0x0052,  0x0053,  0x0054,  0x0055,  0x0056,  0x0057,
  0x0058,  0x0059,  0x005A,  0x005B,  0x005C,  0x005D,  0x005E,  0x005F,
  0x0060,  0x0041,  0x0042,  0x0043,  0x0044,  0x0045,  0x0046,  0x0047,
  0x0048,  0x0049,  0x004A,  0x004B,  0x004C,  0x004D,  0x004E,  0x004F,
  0x0050,  0x0051,  0x0052,  0x0053,  0x0054,  0x0055,  0x0056,  0x0057,
  0x0058,  0x0059,  0x005A,  0x007B,  0x007C,  0x007D,  0x007E,  0x007F,
  0x0080,  0x0081,  0x0082,  0x0083,  0x0084,  0x0085,  0x0086,  0x0087,
  0x0088,  0x0089,  0x008A,  0x008B,  0x008C,  0x008D,  0x008E,  0x008F,
  0x0090,  0x0091,  0x0092,  0x0093,  0x0094,  0x0095,  0x0096,  0x0097,
  0x0098,  0x0099,  0x009A,  0x009B,  0x009C,  0x009D,  0x009E,  0x009F,
  0x00A0,  0x00A1,  0x00A2,  0x00A3,  0x00A4,  0x00A5,  0x00A6,  0x00A7,
  0x00A8,  0x00A9,  0x00AA,  0x00AB,  0x00AC,  0x00AD,  0x00AE,  0x00AF,
  0x00B0,  0x00B1,  0x00B2,  0x00B3,  0x00B4,  0x039C,  0x00B6,  0x00B7,
  0x00B8,  0x00B9,  0x00BA,  0x00BB,  0x00BC,  0x00BD,  0x00BE,  0x00BF,
  0x00C0,  0x00C1,  0x00C2,  0x00C3,  0x00C4,  0x00C5,  0x00C6,  0x00C7,
  0x00C8,  0x00C9,  0x00CA,  0x00CB,  0x00CC,  0x00CD,  0x00CE,  0x00CF,
  0x00D0,  0x00D1,  0x00D2,  0x00D3,  0x00D4,  0x00D5,  0x00D6,  0x00D7,
  0x00D8,  0x00D9,  0x00DA,  0x00DB,  0x00DC,  0x00DD,  0x00DE,  0x00DF,
  0x00C0,  0x00C1,  0x00C2,  0x00C3,  0x00C4,  0x00C5,  0x00C6,  0x00C7,
  0x00C8,  0x00C9,  0x00CA,  0x00CB,  0x00CC,  0x00CD,  0x00CE,  0x00CF,
  0x00D0,  0x00D1,  0x00D2,  0x00D3,  0x00D4,  0x00D5,  0x00D6,  0x00F7,
  0x00D8,  0x00D9,  0x00DA,  0x00DB,  0x00DC,  0x00DD,  0x00DE,  0x0178,
};

static uint32_t sort00[]={
  0x0000,  0x0001,  0x0002,  0x0003,  0x0004,  0x0005,  0x0006,  0x0007,
  0x0008,  0x0009,  0x000A,  0x000B,  0x000C,  0x000D,  0x000E,  0x000F,
  0x0010,  0x0011,  0x0012,  0x0013,  0x0014,  0x0015,  0x0016,  0x0017,
  0x0018,  0x0019,  0x001A,  0x001B,  0x001C,  0x001D,  0x001E,  0x001F,
  0x0020,  0x0021,  0x0022,  0x0023,  0x0024,  0x0025,  0x0026,  0x0027,
  0x0028,  0x0029,  0x002A,  0x002B,  0x002C,  0x002D,  0x002E,  0x002F,
  0x0030,  0x0031,  0x0032,  0x0033,  0x0034,  0x0035,  0x0036,  0x0037,
  0x0038,  0x0039,  0x003A,  0x003B,  0x003C,  0x003D,  0x003E,  0x003F,
  0x0040,  0x0041,  0x0042,  0x0043,  0x0044,  0x0045,  0x0046,  0x0047,
  0x0048,  0x0049,  0x004A,  0x004B,  0x004C,  0x004D,  0x004E,  0x004F,
  0x0050,  0x0051,  0x0052,  0x0053,  0x0054,  0x0055,  0x0056,  0x0057,
  0x0058,  0x0059,  0x005A,  0x005B,  0x005C,  0x005D,  0x005E,  0x005F,
  0x0060,  0x0041,  0x0042,  0x0043,  0x0044,  0x0045,  0x0046,  0x0047,
  0x0048,  0x0049,  0x004A,  0x004B,  0x004C,  0x004D,  0x004E,  0x004F,
  0x0050,  0x0051,  0x0052,  0x0053,  0x0054,  0x0055,  0x0056,  0x0057,
  0x0058,  0x0059,  0x005A,  0x007B,  0x007C,  0x007D,  0x007E,  0x007F,
  0x0080,  0x0081,  0x0082,  0x0083,  0x0084,  0x0085,  0x0086,  0x0087,
  0x0088,  0x0089,  0x008A,  0x008B,  0x008C,  0x008D,  0x008E,  0x008F,
  0x0090,  0x0091,  0x0092,  0x0093,  0x0094,  0x0095,  0x0096,  0x0097,
  0x0098,  0x0099,  0x009A,  0x009B,  0x009C,  0x009D,  0x009E,  0x009F,
  0x00A0,  0x00A1,  0x00A2,  0x00A3,  0x00A4,  0x00A5,  0x00A6,  0x00A7,
  0x00A8,  0x00A9,  0x00AA,  0x00AB,  0x00AC,  0x00AD,  0x00AE,  0x00AF,
  0x00B0,  0x00B1,  0x00B2,  0x00B3,  0x00B4,  0x039C,  0x00B6,  0x00B7,
  0x00B8,  0x00B9,  0x00BA,  0x00BB,  0x00BC,  0x00BD,  0x00BE,  0x00BF,
  0x0041,  0x0041,  0x0041,  0x0041,  0x0041,  0x0041,  0x00C6,  0x0043,
  0x0045,  0x0045,  0x0045,  0x0045,  0x0049,  0x0049,  0x0049,  0x0049,
  0x00D0,  0x004E,  0x004F,  0x004F,  0x004F,  0x004F,  0x004F,  0x00D7,
  0x00D8,  0x0055,  0x0055,  0x0055,  0x0055,  0x0059,  0x00DE,  0x0053,
  0x0041,  0x0041,  0x0041,  0x0041,  0x0041,  0x0041,  0x00C6,  0x0043,
  0x0045,  0x0045,  0x0045,  0x0045,  0x0049,  0x0049,  0x0049,  0x0049,
  0x00D0,  0x004E,  0x004F,  0x004F,  0x004F,  0x004F,  0x004F,  0x00F7,
  0x00D8,  0x0055,  0x0055,  0x0055,  0x0055,  0x0059,  0x00DE,  0x0059,
};

static uint32_t lower01[]={
  0x0101,  0x0101,  0x0103,  0x0103,  0x0105,  0x0105,  0x0107,  0x0107,
  0x0109,  0x0109,  0x010B,  0x010B,  0x010D,  0x010D,  0x010F,  0x010F,
  0x0111,  0x0111,  0x0113,  0x0113,  0x0115,  0x0115,  0x0117,  0x0117,
  0x0119,  0x0119,  0x011B,  0x011B,  0x011D,  0x011D,  0x011F,  0x011F,
  0x0121,  0x0121,  0x0123,  0x0123,  0x0125,  0x0125,  0x0127,  0x0127,
  0x0129,  0x0129,  0x012B,  0x012B,  0x012D,  0x012D,  0x012F,  0x012F,
  0x0069,  0x0131,  0x0133,  0x0133,  0x0135,  0x0135,  0x0137,  0x0137,
  0x0138,  0x013A,  0x013A,  0x013C,  0x013C,  0x013E,  0x013E,  0x0140,
  0x0140,  0x0142,  0x0142,  0x0144,  0x0144,  0x0146,  0x0146,  0x0148,
  0x0148,  0x0149,  0x014B,  0x014B,  0x014D,  0x014D,  0x014F,  0x014F,
  0x0151,  0x0151,  0x0153,  0x0153,  0x0155,  0x0155,  0x0157,  0x0157,
  0x0159,  0x0159,  0x015B,  0x015B,  0x015D,  0x015D,  0x015F,  0x015F,
  0x0161,  0x0161,  0x0163,  0x0163,  0x0165,  0x0165,  0x0167,  0x0167,
  0x0169,  0x0169,  0x016B,  0x016B,  0x016D,  0x016D,  0x016F,  0x016F,
  0x0171,  0x0171,  0x0173,  0x0173,  0x0175,  0x0175,  0x0177,  0x0177,
  0x00FF,  0x017A,  0x017A,  0x017C,  0x017C,  0x017E,  0x017E,  0x017F,
  0x0180,  0x0253,  0x0183,  0x0183,  0x0185,  0x0185,  0x0254,  0x0188,
  0x0188,  0x0256,  0x0257,  0x018C,  0x018C,  0x018D,  0x01DD,  0x0259,
  0x025B,  0x0192,  0x0192,  0x0260,  0x0263,  0x0195,  0x0269,  0x0268,
  0x0199,  0x0199,  0x019A,  0x019B,  0x026F,  0x0272,  0x019E,  0x0275,
  0x01A1,  0x01A1,  0x01A3,  0x01A3,  0x01A5,  0x01A5,  0x0280,  0x01A8,
  0x01A8,  0x0283,  0x01AA,  0x01AB,  0x01AD,  0x01AD,  0x0288,  0x01B0,
  0x01B0,  0x028A,  0x028B,  0x01B4,  0x01B4,  0x01B6,  0x01B6,  0x0292,
  0x01B9,  0x01B9,  0x01BA,  0x01BB,  0x01BD,  0x01BD,  0x01BE,  0x01BF,
  0x01C0,  0x01C1,  0x01C2,  0x01C3,  0x01C6,  0x01C6,  0x01C6,  0x01C9,
  0x01C9,  0x01C9,  0x01CC,  0x01CC,  0x01CC,  0x01CE,  0x01CE,  0x01D0,
  0x01D0,  0x01D2,  0x01D2,  0x01D4,  0x01D4,  0x01D6,  0x01D6,  0x01D8,
  0x01D8,  0x01DA,  0x01DA,  0x01DC,  0x01DC,  0x01DD,  0x01DF,  0x01DF,
  0x01E1,  0x01E1,  0x01E3,  0x01E3,  0x01E5,  0x01E5,  0x01E7,  0x01E7,
  0x01E9,  0x01E9,  0x01EB,  0x01EB,  0x01ED,  0x01ED,  0x01EF,  0x01EF,
  0x01F0,  0x01F3,  0x01F3,  0x01F3,  0x01F5,  0x01F5,  0x0195,  0x01BF,
  0x01F9,  0x01F9,  0x01FB,  0x01FB,  0x01FD,  0x01FD,  0x01FF,  0x01FF,
};

static uint32_t upper01[]={
  0x0100,  0x0100,  0x0102,  0x0102,  0x0104,  0x0104,  0x0106,  0x0106,
  0x0108,  0x0108,  0x010A,  0x010A,  0x010C,  0x010C,  0x010E,  0x010E,
  0x0110,  0x0110,  0x0112,  0x0112,  0x0114,  0x0114,  0x0116,  0x0116,
  0x0118,  0x0118,  0x011A,  0x011A,  0x011C,  0x011C,  0x011E,  0x011E,
  0x0120,  0x0120,  0x0122,  0x0122,  0x0124,  0x0124,  0x0126,  0x0126,
  0x0128,  0x0128,  0x012A,  0x012A,  0x012C,  0x012C,  0x012E,  0x012E,
  0x0130,  0x0049,  0x0132,  0x0132,  0x0134,  0x0134,  0x0136,  0x0136,
  0x0138,  0x0139,  0x0139,  0x013B,  0x013B,  0x013D,  0x013D,  0x013F,
  0x013F,  0x0141,  0x0141,  0x0143,  0x0143,  0x0145,  0x0145,  0x0147,
  0x0147,  0x0149,  0x014A,  0x014A,  0x014C,  0x014C,  0x014E,  0x014E,
  0x0150,  0x0150,  0x0152,  0x0152,  0x0154,  0x0154,  0x0156,  0x0156,
  0x0158,  0x0158,  0x015A,  0x015A,  0x015C,  0x015C,  0x015E,  0x015E,
  0x0160,  0x0160,  0x0162,  0x0162,  0x0164,  0x0164,  0x0166,  0x0166,
  0x0168,  0x0168,  0x016A,  0x016A,  0x016C,  0x016C,  0x016E,  0x016E,
  0x0170,  0x0170,  0x0172,  0x0172,  0x0174,  0x0174,  0x0176,  0x0176,
  0x0178,  0x0179,  0x0179,  0x017B,  0x017B,  0x017D,  0x017D,  0x0053,
  0x0180,  0x0181,  0x0182,  0x0182,  0x0184,  0x0184,  0x0186,  0x0187,
  0x0187,  0x0189,  0x018A,  0x018B,  0x018B,  0x018D,  0x018E,  0x018F,
  0x0190,  0x0191,  0x0191,  0x0193,  0x0194,  0x01F6,  0x0196,  0x0197,
  0x0198,  0x0198,  0x019A,  0x019B,  0x019C,  0x019D,  0x019E,  0x019F,
  0x01A0,  0x01A0,  0x01A2,  0x01A2,  0x01A4,  0x01A4,  0x01A6,  0x01A7,
  0x01A7,  0x01A9,  0x01AA,  0x01AB,  0x01AC,  0x01AC,  0x01AE,  0x01AF,
  0x01AF,  0x01B1,  0x01B2,  0x01B3,  0x01B3,  0x01B5,  0x01B5,  0x01B7,
  0x01B8,  0x01B8,  0x01BA,  0x01BB,  0x01BC,  0x01BC,  0x01BE,  0x01F7,
  0x01C0,  0x01C1,  0x01C2,  0x01C3,  0x01C4,  0x01C4,  0x01C4,  0x01C7,
  0x01C7,  0x01C7,  0x01CA,  0x01CA,  0x01CA,  0x01CD,  0x01CD,  0x01CF,
  0x01CF,  0x01D1,  0x01D1,  0x01D3,  0x01D3,  0x01D5,  0x01D5,  0x01D7,
  0x01D7,  0x01D9,  0x01D9,  0x01DB,  0x01DB,  0x018E,  0x01DE,  0x01DE,
  0x01E0,  0x01E0,  0x01E2,  0x01E2,  0x01E4,  0x01E4,  0x01E6,  0x01E6,
  0x01E8,  0x01E8,  0x01EA,  0x01EA,  0x01EC,  0x01EC,  0x01EE,  0x01EE,
  0x01F0,  0x01F1,  0x01F1,  0x01F1,  0x01F4,  0x01F4,  0x01F6,  0x01F7,
  0x01F8,  0x01F8,  0x01FA,  0x01FA,  0x01FC,  0x01FC,  0x01FE,  0x01FE,
};

static uint32_t sort01[]={
  0x0041,  0x0041,  0x0041,  0x0041,  0x0041,  0x0041,  0x0043,  0x0043,
  0x0043,  0x0043,  0x0043,  0x0043,  0x0043,  0x0043,  0x0044,  0x0044,
  0x0110,  0x0110,  0x0045,  0x0045,  0x0045,  0x0045,  0x0045,  0x0045,
  0x0045,  0x0045,  0x0045,  0x0045,  0x0047,  0x0047,  0x0047,  0x0047,
  0x0047,  0x0047,  0x0047,  0x0047,  0x0048,  0x0048,  0x0126,  0x0126,
  0x0049,  0x0049,  0x0049,  0x0049,  0x0049,  0x0049,  0x0049,  0x0049,
  0x0049,  0x0049,  0x0132,  0x0132,  0x004A,  0x004A,  0x004B,  0x004B,
  0x0138,  0x004C,  0x004C,  0x004C,  0x004C,  0x004C,  0x004C,  0x013F,
  0x013F,  0x0141,  0x0141,  0x004E,  0x004E,  0x004E,  0x004E,  0x004E,
  0x004E,  0x0149,  0x014A,  0x014A,  0x004F,  0x004F,  0x004F,  0x004F,
  0x004F,  0x004F,  0x0152,  0x0152,  0x0052,  0x0052,  0x0052,  0x0052,
  0x0052,  0x0052,  0x0053,  0x0053,  0x0053,  0x0053,  0x0053,  0x0053,
  0x0053,  0x0053,  0x0054,  0x0054,  0x0054,  0x0054,  0x0166,  0x0166,
  0x0055,  0x0055,  0x0055,  0x0055,  0x0055,  0x0055,  0x0055,  0x0055,
  0x0055,  0x0055,  0x0055,  0x0055,  0x0057,  0x0057,  0x0059,  0x0059,
  0x0059,  0x005A,  0x005A,  0x005A,  0x005A,  0x005A,  0x005A,  0x0053,
  0x0180,  0x0181,  0x0182,  0x0182,  0x0184,  0x0184,  0x0186,  0x0187,
  0x0187,  0x0189,  0x018A,  0x018B,  0x018B,  0x018D,  0x018E,  0x018F,
  0x0190,  0x0191,  0x0191,  0x0193,  0x0194,  0x01F6,  0x0196,  0x0197,
  0x0198,  0x0198,  0x019A,  0x019B,  0x019C,  0x019D,  0x019E,  0x019F,
  0x004F,  0x004F,  0x01A2,  0x01A2,  0x01A4,  0x01A4,  0x01A6,  0x01A7,
  0x01A7,  0x01A9,  0x01AA,  0x01AB,  0x01AC,  0x01AC,  0x01AE,  0x0055,
  0x0055,  0x01B1,  0x01B2,  0x01B3,  0x01B3,  0x01B5,  0x01B5,  0x01B7,
  0x01B8,  0x01B8,  0x01BA,  0x01BB,  0x01BC,  0x01BC,  0x01BE,  0x01F7,
  0x01C0,  0x01C1,  0x01C2,  0x01C3,  0x01C4,  0x01C4,  0x01C4,  0x01C7,
  0x01C7,  0x01C7,  0x01CA,  0x01CA,  0x01CA,  0x0041,  0x0041,  0x0049,
  0x0049,  0x004F,  0x004F,  0x0055,  0x0055,  0x0055,  0x0055,  0x0055,
  0x0055,  0x0055,  0x0055,  0x0055,  0x0055,  0x018E,  0x0041,  0x0041,
  0x0041,  0x0041,  0x00C6,  0x00C6,  0x01E4,  0x01E4,  0x0047,  0x0047,
  0x004B,  0x004B,  0x004F,  0x004F,  0x004F,  0x004F,  0x01B7,  0x01B7,
  0x004A,  0x01F1,  0x01F1,  0x01F1,  0x0047,  0x0047,  0x01F6,  0x01F7,
  0x004E,  0x004E,  0x0041,  0x0041,  0x00C6,  0x00C6,  0x00D8,  0x00D8,
};

static uint32_t lower02[]={
  0x0201,  0x0201,  0x0203,  0x0203,  0x0205,  0x0205,  0x0207,  0x0207,
  0x0209,  0x0209,  0x020B,  0x020B,  0x020D,  0x020D,  0x020F,  0x020F,
  0x0211,  0x0211,  0x0213,  0x0213,  0x0215,  0x0215,  0x0217,  0x0217,
  0x0219,  0x0219,  0x021B,  0x021B,  0x021D,  0x021D,  0x021F,  0x021F,
  0x0220,  0x0221,  0x0223,  0x0223,  0x0225,  0x0225,  0x0227,  0x0227,
  0x0229,  0x0229,  0x022B,  0x022B,  0x022D,  0x022D,  0x022F,  0x022F,
  0x0231,  0x0231,  0x0233,  0x0233,  0x0234,  0x0235,  0x0236,  0x0237,
  0x0238,  0x0239,  0x023A,  0x023B,  0x023C,  0x023D,  0x023E,  0x023F,
  0x0240,  0x0241,  0x0242,  0x0243,  0x0244,  0x0245,  0x0246,  0x0247,
  0x0248,  0x0249,  0x024A,  0x024B,  0x024C,  0x024D,  0x024E,  0x024F,
  0x0250,  0x0251,  0x0252,  0x0253,  0x0254,  0x0255,  0x0256,  0x0257,
  0x0258,  0x0259,  0x025A,  0x025B,  0x025C,  0x025D,  0x025E,  0x025F,
  0x0260,  0x0261,  0x0262,  0x0263,  0x0264,  0x0265,  0x0266,  0x0267,
  0x0268,  0x0269,  0x026A,  0x026B,  0x026C,  0x026D,  0x026E,  0x026F,
  0x0270,  0x0271,  0x0272,  0x0273,  0x0274,  0x0275,  0x0276,  0x0277,
  0x0278,  0x0279,  0x027A,  0x027B,  0x027C,  0x027D,  0x027E,  0x027F,
  0x0280,  0x0281,  0x0282,  0x0283,  0x0284,  0x0285,  0x0286,  0x0287,
  0x0288,  0x0289,  0x028A,  0x028B,  0x028C,  0x028D,  0x028E,  0x028F,
  0x0290,  0x0291,  0x0292,  0x0293,  0x0294,  0x0295,  0x0296,  0x0297,
  0x0298,  0x0299,  0x029A,  0x029B,  0x029C,  0x029D,  0x029E,  0x029F,
  0x02A0,  0x02A1,  0x02A2,  0x02A3,  0x02A4,  0x02A5,  0x02A6,  0x02A7,
  0x02A8,  0x02A9,  0x02AA,  0x02AB,  0x02AC,  0x02AD,  0x02AE,  0x02AF,
  0x02B0,  0x02B1,  0x02B2,  0x02B3,  0x02B4,  0x02B5,  0x02B6,  0x02B7,
  0x02B8,  0x02B9,  0x02BA,  0x02BB,  0x02BC,  0x02BD,  0x02BE,  0x02BF,
  0x02C0,  0x02C1,  0x02C2,  0x02C3,  0x02C4,  0x02C5,  0x02C6,  0x02C7,
  0x02C8,  0x02C9,  0x02CA,  0x02CB,  0x02CC,  0x02CD,  0x02CE,  0x02CF,
  0x02D0,  0x02D1,  0x02D2,  0x02D3,  0x02D4,  0x02D5,  0x02D6,  0x02D7,
  0x02D8,  0x02D9,  0x02DA,  0x02DB,  0x02DC,  0x02DD,  0x02DE,  0x02DF,
  0x02E0,  0x02E1,  0x02E2,  0x02E3,  0x02E4,  0x02E5,  0x02E6,  0x02E7,
  0x02E8,  0x02E9,  0x02EA,  0x02EB,  0x02EC,  0x02ED,  0x02EE,  0x02EF,
  0x02F0,  0x02F1,  0x02F2,  0x02F3,  0x02F4,  0x02F5,  0x02F6,  0x02F7,
  0x02F8,  0x02F9,  0x02FA,  0x02FB,  0x02FC,  0x02FD,  0x02FE,  0x02FF,
};

static uint32_t upper02[]={
  0x0200,  0x0200,  0x0202,  0x0202,  0x0204,  0x0204,  0x0206,  0x0206,
  0x0208,  0x0208,  0x020A,  0x020A,  0x020C,  0x020C,  0x020E,  0x020E,
  0x0210,  0x0210,  0x0212,  0x0212,  0x0214,  0x0214,  0x0216,  0x0216,
  0x0218,  0x0218,  0x021A,  0x021A,  0x021C,  0x021C,  0x021E,  0x021E,
  0x0220,  0x0221,  0x0222,  0x0222,  0x0224,  0x0224,  0x0226,  0x0226,
  0x0228,  0x0228,  0x022A,  0x022A,  0x022C,  0x022C,  0x022E,  0x022E,
  0x0230,  0x0230,  0x0232,  0x0232,  0x0234,  0x0235,  0x0236,  0x0237,
  0x0238,  0x0239,  0x023A,  0x023B,  0x023C,  0x023D,  0x023E,  0x023F,
  0x0240,  0x0241,  0x0242,  0x0243,  0x0244,  0x0245,  0x0246,  0x0247,
  0x0248,  0x0249,  0x024A,  0x024B,  0x024C,  0x024D,  0x024E,  0x024F,
  0x0250,  0x0251,  0x0252,  0x0181,  0x0186,  0x0255,  0x0189,  0x018A,
  0x0258,  0x018F,  0x025A,  0x0190,  0x025C,  0x025D,  0x025E,  0x025F,
  0x0193,  0x0261,  0x0262,  0x0194,  0x0264,  0x0265,  0x0266,  0x0267,
  0x0197,  0x0196,  0x026A,  0x026B,  0x026C,  0x026D,  0x026E,  0x019C,
  0x0270,  0x0271,  0x019D,  0x0273,  0x0274,  0x019F,  0x0276,  0x0277,
  0x0278,  0x0279,  0x027A,  0x027B,  0x027C,  0x027D,  0x027E,  0x027F,
  0x01A6,  0x0281,  0x0282,  0x01A9,  0x0284,  0x0285,  0x0286,  0x0287,
  0x01AE,  0x0289,  0x01B1,  0x01B2,  0x028C,  0x028D,  0x028E,  0x028F,
  0x0290,  0x0291,  0x01B7,  0x0293,  0x0294,  0x0295,  0x0296,  0x0297,
  0x0298,  0x0299,  0x029A,  0x029B,  0x029C,  0x029D,  0x029E,  0x029F,
  0x02A0,  0x02A1,  0x02A2,  0x02A3,  0x02A4,  0x02A5,  0x02A6,  0x02A7,
  0x02A8,  0x02A9,  0x02AA,  0x02AB,  0x02AC,  0x02AD,  0x02AE,  0x02AF,
  0x02B0,  0x02B1,  0x02B2,  0x02B3,  0x02B4,  0x02B5,  0x02B6,  0x02B7,
  0x02B8,  0x02B9,  0x02BA,  0x02BB,  0x02BC,  0x02BD,  0x02BE,  0x02BF,
  0x02C0,  0x02C1,  0x02C2,  0x02C3,  0x02C4,  0x02C5,  0x02C6,  0x02C7,
  0x02C8,  0x02C9,  0x02CA,  0x02CB,  0x02CC,  0x02CD,  0x02CE,  0x02CF,
  0x02D0,  0x02D1,  0x02D2,  0x02D3,  0x02D4,  0x02D5,  0x02D6,  0x02D7,
  0x02D8,  0x02D9,  0x02DA,  0x02DB,  0x02DC,  0x02DD,  0x02DE,  0x02DF,
  0x02E0,  0x02E1,  0x02E2,  0x02E3,  0x02E4,  0x02E5,  0x02E6,  0x02E7,
  0x02E8,  0x02E9,  0x02EA,  0x02EB,  0x02EC,  0x02ED,  0x02EE,  0x02EF,
  0x02F0,  0x02F1,  0x02F2,  0x02F3,  0x02F4,  0x02F5,  0x02F6,  0x02F7,
  0x02F8,  0x02F9,  0x02FA,  0x02FB,  0x02FC,  0x02FD,  0x02FE,  0x02FF,
};

static uint32_t sort02[]={
  0x0041,  0x0041,  0x0041,  0x0041,  0x0045,  0x0045,  0x0045,  0x0045,
  0x0049,  0x0049,  0x0049,  0x0049,  0x004F,  0x004F,  0x004F,  0x004F,
  0x0052,  0x0052,  0x0052,  0x0052,  0x0055,  0x0055,  0x0055,  0x0055,
  0x0053,  0x0053,  0x0054,  0x0054,  0x021C,  0x021C,  0x0048,  0x0048,
  0x0220,  0x0221,  0x0222,  0x0222,  0x0224,  0x0224,  0x0041,  0x0041,
  0x0045,  0x0045,  0x004F,  0x004F,  0x004F,  0x004F,  0x004F,  0x004F,
  0x004F,  0x004F,  0x0059,  0x0059,  0x0234,  0x0235,  0x0236,  0x0237,
  0x0238,  0x0239,  0x023A,  0x023B,  0x023C,  0x023D,  0x023E,  0x023F,
  0x0240,  0x0241,  0x0242,  0x0243,  0x0244,  0x0245,  0x0246,  0x0247,
  0x0248,  0x0249,  0x024A,  0x024B,  0x024C,  0x024D,  0x024E,  0x024F,
  0x0250,  0x0251,  0x0252,  0x0181,  0x0186,  0x0255,  0x0189,  0x018A,
  0x0258,  0x018F,  0x025A,  0x0190,  0x025C,  0x025D,  0x025E,  0x025F,
  0x0193,  0x0261,  0x0262,  0x0194,  0x0264,  0x0265,  0x0266,  0x0267,
  0x0197,  0x0196,  0x026A,  0x026B,  0x026C,  0x026D,  0x026E,  0x019C,
  0x0270,  0x0271,  0x019D,  0x0273,  0x0274,  0x019F,  0x0276,  0x0277,
  0x0278,  0x0279,  0x027A,  0x027B,  0x027C,  0x027D,  0x027E,  0x027F,
  0x01A6,  0x0281,  0x0282,  0x01A9,  0x0284,  0x0285,  0x0286,  0x0287,
  0x01AE,  0x0289,  0x01B1,  0x01B2,  0x028C,  0x028D,  0x028E,  0x028F,
  0x0290,  0x0291,  0x01B7,  0x0293,  0x0294,  0x0295,  0x0296,  0x0297,
  0x0298,  0x0299,  0x029A,  0x029B,  0x029C,  0x029D,  0x029E,  0x029F,
  0x02A0,  0x02A1,  0x02A2,  0x02A3,  0x02A4,  0x02A5,  0x02A6,  0x02A7,
  0x02A8,  0x02A9,  0x02AA,  0x02AB,  0x02AC,  0x02AD,  0x02AE,  0x02AF,
  0x02B0,  0x02B1,  0x02B2,  0x02B3,  0x02B4,  0x02B5,  0x02B6,  0x02B7,
  0x02B8,  0x02B9,  0x02BA,  0x02BB,  0x02BC,  0x02BD,  0x02BE,  0x02BF,
  0x02C0,  0x02C1,  0x02C2,  0x02C3,  0x02C4,  0x02C5,  0x02C6,  0x02C7,
  0x02C8,  0x02C9,  0x02CA,  0x02CB,  0x02CC,  0x02CD,  0x02CE,  0x02CF,
  0x02D0,  0x02D1,  0x02D2,  0x02D3,  0x02D4,  0x02D5,  0x02D6,  0x02D7,
  0x02D8,  0x02D9,  0x02DA,  0x02DB,  0x02DC,  0x02DD,  0x02DE,  0x02DF,
  0x02E0,  0x02E1,  0x02E2,  0x02E3,  0x02E4,  0x02E5,  0x02E6,  0x02E7,
  0x02E8,  0x02E9,  0x02EA,  0x02EB,  0x02EC,  0x02ED,  0x02EE,  0x02EF,
  0x02F0,  0x02F1,  0x02F2,  0x02F3,  0x02F4,  0x02F5,  0x02F6,  0x02F7,
  0x02F8,  0x02F9,  0x02FA,  0x02FB,  0x02FC,  0x02FD,  0x02FE,  0x02FF,
};

static uint32_t lower03[]={
  0x0300,  0x0301,  0x0302,  0x0303,  0x0304,  0x0305,  0x0306,  0x0307,
  0x0308,  0x0309,  0x030A,  0x030B,  0x030C,  0x030D,  0x030E,  0x030F,
  0x0310,  0x0311,  0x0312,  0x0313,  0x0314,  0x0315,  0x0316,  0x0317,
  0x0318,  0x0319,  0x031A,  0x031B,  0x031C,  0x031D,  0x031E,  0x031F,
  0x0320,  0x0321,  0x0322,  0x0323,  0x0324,  0x0325,  0x0326,  0x0327,
  0x0328,  0x0329,  0x032A,  0x032B,  0x032C,  0x032D,  0x032E,  0x032F,
  0x0330,  0x0331,  0x0332,  0x0333,  0x0334,  0x0335,  0x0336,  0x0337,
  0x0338,  0x0339,  0x033A,  0x033B,  0x033C,  0x033D,  0x033E,  0x033F,
  0x0340,  0x0341,  0x0342,  0x0343,  0x0344,  0x0345,  0x0346,  0x0347,
  0x0348,  0x0349,  0x034A,  0x034B,  0x034C,  0x034D,  0x034E,  0x034F,
  0x0350,  0x0351,  0x0352,  0x0353,  0x0354,  0x0355,  0x0356,  0x0357,
  0x0358,  0x0359,  0x035A,  0x035B,  0x035C,  0x035D,  0x035E,  0x035F,
  0x0360,  0x0361,  0x0362,  0x0363,  0x0364,  0x0365,  0x0366,  0x0367,
  0x0368,  0x0369,  0x036A,  0x036B,  0x036C,  0x036D,  0x036E,  0x036F,
  0x0370,  0x0371,  0x0372,  0x0373,  0x0374,  0x0375,  0x0376,  0x0377,
  0x0378,  0x0379,  0x037A,  0x037B,  0x037C,  0x037D,  0x037E,  0x037F,
  0x0380,  0x0381,  0x0382,  0x0383,  0x0384,  0x0385,  0x03AC,  0x0387,
  0x03AD,  0x03AE,  0x03AF,  0x038B,  0x03CC,  0x038D,  0x03CD,  0x03CE,
  0x0390,  0x03B1,  0x03B2,  0x03B3,  0x03B4,  0x03B5,  0x03B6,  0x03B7,
  0x03B8,  0x03B9,  0x03BA,  0x03BB,  0x03BC,  0x03BD,  0x03BE,  0x03BF,
  0x03C0,  0x03C1,  0x03A2,  0x03C3,  0x03C4,  0x03C5,  0x03C6,  0x03C7,
  0x03C8,  0x03C9,  0x03CA,  0x03CB,  0x03AC,  0x03AD,  0x03AE,  0x03AF,
  0x03B0,  0x03B1,  0x03B2,  0x03B3,  0x03B4,  0x03B5,  0x03B6,  0x03B7,
  0x03B8,  0x03B9,  0x03BA,  0x03BB,  0x03BC,  0x03BD,  0x03BE,  0x03BF,
  0x03C0,  0x03C1,  0x03C2,  0x03C3,  0x03C4,  0x03C5,  0x03C6,  0x03C7,
  0x03C8,  0x03C9,  0x03CA,  0x03CB,  0x03CC,  0x03CD,  0x03CE,  0x03CF,
  0x03D0,  0x03D1,  0x03D2,  0x03D3,  0x03D4,  0x03D5,  0x03D6,  0x03D7,
  0x03D8,  0x03D9,  0x03DB,  0x03DB,  0x03DD,  0x03DD,  0x03DF,  0x03DF,
  0x03E1,  0x03E1,  0x03E3,  0x03E3,  0x03E5,  0x03E5,  0x03E7,  0x03E7,
  0x03E9,  0x03E9,  0x03EB,  0x03EB,  0x03ED,  0x03ED,  0x03EF,  0x03EF,
  0x03F0,  0x03F1,  0x03F2,  0x03F3,  0x03F4,  0x03F5,  0x03F6,  0x03F7,
  0x03F8,  0x03F9,  0x03FA,  0x03FB,  0x03FC,  0x03FD,  0x03FE,  0x03FF,
};

static uint32_t upper03[]={
  0x0300,  0x0301,  0x0302,  0x0303,  0x0304,  0x0305,  0x0306,  0x0307,
  0x0308,  0x0309,  0x030A,  0x030B,  0x030C,  0x030D,  0x030E,  0x030F,
  0x0310,  0x0311,  0x0312,  0x0313,  0x0314,  0x0315,  0x0316,  0x0317,
  0x0318,  0x0319,  0x031A,  0x031B,  0x031C,  0x031D,  0x031E,  0x031F,
  0x0320,  0x0321,  0x0322,  0x0323,  0x0324,  0x0325,  0x0326,  0x0327,
  0x0328,  0x0329,  0x032A,  0x032B,  0x032C,  0x032D,  0x032E,  0x032F,
  0x0330,  0x0331,  0x0332,  0x0333,  0x0334,  0x0335,  0x0336,  0x0337,
  0x0338,  0x0339,  0x033A,  0x033B,  0x033C,  0x033D,  0x033E,  0x033F,
  0x0340,  0x0341,  0x0342,  0x0343,  0x0344,  0x0399,  0x0346,  0x0347,
  0x0348,  0x0349,  0x034A,  0x034B,  0x034C,  0x034D,  0x034E,  0x034F,
  0x0350,  0x0351,  0x0352,  0x0353,  0x0354,  0x0355,  0x0356,  0x0357,
  0x0358,  0x0359,  0x035A,  0x035B,  0x035C,  0x035D,  0x035E,  0x035F,
  0x0360,  0x0361,  0x0362,  0x0363,  0x0364,  0x0365,  0x0366,  0x0367,
  0x0368,  0x0369,  0x036A,  0x036B,  0x036C,  0x036D,  0x036E,  0x036F,
  0x0370,  0x0371,  0x0372,  0x0373,  0x0374,  0x0375,  0x0376,  0x0377,
  0x0378,  0x0379,  0x037A,  0x037B,  0x037C,  0x037D,  0x037E,  0x037F,
  0x0380,  0x0381,  0x0382,  0x0383,  0x0384,  0x0385,  0x0386,  0x0387,
  0x0388,  0x0389,  0x038A,  0x038B,  0x038C,  0x038D,  0x038E,  0x038F,
  0x0390,  0x0391,  0x0392,  0x0393,  0x0394,  0x0395,  0x0396,  0x0397,
  0x0398,  0x0399,  0x039A,  0x039B,  0x039C,  0x039D,  0x039E,  0x039F,
  0x03A0,  0x03A1,  0x03A2,  0x03A3,  0x03A4,  0x03A5,  0x03A6,  0x03A7,
  0x03A8,  0x03A9,  0x03AA,  0x03AB,  0x0386,  0x0388,  0x0389,  0x038A,
  0x03B0,  0x0391,  0x0392,  0x0393,  0x0394,  0x0395,  0x0396,  0x0397,
  0x0398,  0x0399,  0x039A,  0x039B,  0x039C,  0x039D,  0x039E,  0x039F,
  0x03A0,  0x03A1,  0x03A3,  0x03A3,  0x03A4,  0x03A5,  0x03A6,  0x03A7,
  0x03A8,  0x03A9,  0x03AA,  0x03AB,  0x038C,  0x038E,  0x038F,  0x03CF,
  0x0392,  0x0398,  0x03D2,  0x03D3,  0x03D4,  0x03A6,  0x03A0,  0x03D7,
  0x03D8,  0x03D9,  0x03DA,  0x03DA,  0x03DC,  0x03DC,  0x03DE,  0x03DE,
  0x03E0,  0x03E0,  0x03E2,  0x03E2,  0x03E4,  0x03E4,  0x03E6,  0x03E6,
  0x03E8,  0x03E8,  0x03EA,  0x03EA,  0x03EC,  0x03EC,  0x03EE,  0x03EE,
  0x039A,  0x03A1,  0x03A3,  0x03F3,  0x03F4,  0x03F5,  0x03F6,  0x03F7,
  0x03F8,  0x03F9,  0x03FA,  0x03FB,  0x03FC,  0x03FD,  0x03FE,  0x03FF,
};

static uint32_t sort03[]={
  0x0300,  0x0301,  0x0302,  0x0303,  0x0304,  0x0305,  0x0306,  0x0307,
  0x0308,  0x0309,  0x030A,  0x030B,  0x030C,  0x030D,  0x030E,  0x030F,
  0x0310,  0x0311,  0x0312,  0x0313,  0x0314,  0x0315,  0x0316,  0x0317,
  0x0318,  0x0319,  0x031A,  0x031B,  0x031C,  0x031D,  0x031E,  0x031F,
  0x0320,  0x0321,  0x0322,  0x0323,  0x0324,  0x0325,  0x0326,  0x0327,
  0x0328,  0x0329,  0x032A,  0x032B,  0x032C,  0x032D,  0x032E,  0x032F,
  0x0330,  0x0331,  0x0332,  0x0333,  0x0334,  0x0335,  0x0336,  0x0337,
  0x0338,  0x0339,  0x033A,  0x033B,  0x033C,  0x033D,  0x033E,  0x033F,
  0x0340,  0x0341,  0x0342,  0x0343,  0x0344,  0x0399,  0x0346,  0x0347,
  0x0348,  0x0349,  0x034A,  0x034B,  0x034C,  0x034D,  0x034E,  0x034F,
  0x0350,  0x0351,  0x0352,  0x0353,  0x0354,  0x0355,  0x0356,  0x0357,
  0x0358,  0x0359,  0x035A,  0x035B,  0x035C,  0x035D,  0x035E,  0x035F,
  0x0360,  0x0361,  0x0362,  0x0363,  0x0364,  0x0365,  0x0366,  0x0367,
  0x0368,  0x0369,  0x036A,  0x036B,  0x036C,  0x036D,  0x036E,  0x036F,
  0x0370,  0x0371,  0x0372,  0x0373,  0x0374,  0x0375,  0x0376,  0x0377,
  0x0378,  0x0379,  0x037A,  0x037B,  0x037C,  0x037D,  0x037E,  0x037F,
  0x0380,  0x0381,  0x0382,  0x0383,  0x0384,  0x0385,  0x0391,  0x0387,
  0x0395,  0x0397,  0x0399,  0x038B,  0x039F,  0x038D,  0x03A5,  0x03A9,
  0x0399,  0x0391,  0x0392,  0x0393,  0x0394,  0x0395,  0x0396,  0x0397,
  0x0398,  0x0399,  0x039A,  0x039B,  0x039C,  0x039D,  0x039E,  0x039F,
  0x03A0,  0x03A1,  0x03A2,  0x03A3,  0x03A4,  0x03A5,  0x03A6,  0x03A7,
  0x03A8,  0x03A9,  0x0399,  0x03A5,  0x0391,  0x0395,  0x0397,  0x0399,
  0x03A5,  0x0391,  0x0392,  0x0393,  0x0394,  0x0395,  0x0396,  0x0397,
  0x0398,  0x0399,  0x039A,  0x039B,  0x039C,  0x039D,  0x039E,  0x039F,
  0x03A0,  0x03A1,  0x03A3,  0x03A3,  0x03A4,  0x03A5,  0x03A6,  0x03A7,
  0x03A8,  0x03A9,  0x0399,  0x03A5,  0x039F,  0x03A5,  0x03A9,  0x03CF,
  0x0392,  0x0398,  0x03D2,  0x03D2,  0x03D2,  0x03A6,  0x03A0,  0x03D7,
  0x03D8,  0x03D9,  0x03DA,  0x03DA,  0x03DC,  0x03DC,  0x03DE,  0x03DE,
  0x03E0,  0x03E0,  0x03E2,  0x03E2,  0x03E4,  0x03E4,  0x03E6,  0x03E6,
  0x03E8,  0x03E8,  0x03EA,  0x03EA,  0x03EC,  0x03EC,  0x03EE,  0x03EE,
  0x039A,  0x03A1,  0x03A3,  0x03F3,  0x03F4,  0x03F5,  0x03F6,  0x03F7,
  0x03F8,  0x03F9,  0x03FA,  0x03FB,  0x03FC,  0x03FD,  0x03FE,  0x03FF,
};

static uint32_t lower04[]={
  0x0450,  0x0451,  0x0452,  0x0453,  0x0454,  0x0455,  0x0456,  0x0457,
  0x0458,  0x0459,  0x045A,  0x045B,  0x045C,  0x045D,  0x045E,  0x045F,
  0x0430,  0x0431,  0x0432,  0x0433,  0x0434,  0x0435,  0x0436,  0x0437,
  0x0438,  0x0439,  0x043A,  0x043B,  0x043C,  0x043D,  0x043E,  0x043F,
  0x0440,  0x0441,  0x0442,  0x0443,  0x0444,  0x0445,  0x0446,  0x0447,
  0x0448,  0x0449,  0x044A,  0x044B,  0x044C,  0x044D,  0x044E,  0x044F,
  0x0430,  0x0431,  0x0432,  0x0433,  0x0434,  0x0435,  0x0436,  0x0437,
  0x0438,  0x0439,  0x043A,  0x043B,  0x043C,  0x043D,  0x043E,  0x043F,
  0x0440,  0x0441,  0x0442,  0x0443,  0x0444,  0x0445,  0x0446,  0x0447,
  0x0448,  0x0449,  0x044A,  0x044B,  0x044C,  0x044D,  0x044E,  0x044F,
  0x0450,  0x0451,  0x0452,  0x0453,  0x0454,  0x0455,  0x0456,  0x0457,
  0x0458,  0x0459,  0x045A,  0x045B,  0x045C,  0x045D,  0x045E,  0x045F,
  0x0461,  0x0461,  0x0463,  0x0463,  0x0465,  0x0465,  0x0467,  0x0467,
  0x0469,  0x0469,  0x046B,  0x046B,  0x046D,  0x046D,  0x046F,  0x046F,
  0x0471,  0x0471,  0x0473,  0x0473,  0x0475,  0x0475,  0x0477,  0x0477,
  0x0479,  0x0479,  0x047B,  0x047B,  0x047D,  0x047D,  0x047F,  0x047F,
  0x0481,  0x0481,  0x0482,  0x0483,  0x0484,  0x0485,  0x0486,  0x0487,
  0x0488,  0x0489,  0x048A,  0x048B,  0x048D,  0x048D,  0x048F,  0x048F,
  0x0491,  0x0491,  0x0493,  0x0493,  0x0495,  0x0495,  0x0497,  0x0497,
  0x0499,  0x0499,  0x049B,  0x049B,  0x049D,  0x049D,  0x049F,  0x049F,
  0x04A1,  0x04A1,  0x04A3,  0x04A3,  0x04A5,  0x04A5,  0x04A7,  0x04A7,
  0x04A9,  0x04A9,  0x04AB,  0x04AB,  0x04AD,  0x04AD,  0x04AF,  0x04AF,
  0x04B1,  0x04B1,  0x04B3,  0x04B3,  0x04B5,  0x04B5,  0x04B7,  0x04B7,
  0x04B9,  0x04B9,  0x04BB,  0x04BB,  0x04BD,  0x04BD,  0x04BF,  0x04BF,
  0x04C0,  0x04C2,  0x04C2,  0x04C4,  0x04C4,  0x04C5,  0x04C6,  0x04C8,
  0x04C8,  0x04C9,  0x04CA,  0x04CC,  0x04CC,  0x04CD,  0x04CE,  0x04CF,
  0x04D1,  0x04D1,  0x04D3,  0x04D3,  0x04D5,  0x04D5,  0x04D7,  0x04D7,
  0x04D9,  0x04D9,  0x04DB,  0x04DB,  0x04DD,  0x04DD,  0x04DF,  0x04DF,
  0x04E1,  0x04E1,  0x04E3,  0x04E3,  0x04E5,  0x04E5,  0x04E7,  0x04E7,
  0x04E9,  0x04E9,  0x04EB,  0x04EB,  0x04ED,  0x04ED,  0x04EF,  0x04EF,
  0x04F1,  0x04F1,  0x04F3,  0x04F3,  0x04F5,  0x04F5,  0x04F6,  0x04F7,
  0x04F9,  0x04F9,  0x04FA,  0x04FB,  0x04FC,  0x04FD,  0x04FE,  0x04FF,
};

static uint32_t upper04[]={
  0x0400,  0x0401,  0x0402,  0x0403,  0x0404,  0x0405,  0x0406,  0x0407,
  0x0408,  0x0409,  0x040A,  0x040B,  0x040C,  0x040D,  0x040E,  0x040F,
  0x0410,  0x0411,  0x0412,  0x0413,  0x0414,  0x0415,  0x0416,  0x0417,
  0x0418,  0x0419,  0x041A,  0x041B,  0x041C,  0x041D,  0x041E,  0x041F,
  0x0420,  0x0421,  0x0422,  0x0423,  0x0424,  0x0425,  0x0426,  0x0427,
  0x0428,  0x0429,  0x042A,  0x042B,  0x042C,  0x042D,  0x042E,  0x042F,
  0x0410,  0x0411,  0x0412,  0x0413,  0x0414,  0x0415,  0x0416,  0x0417,
  0x0418,  0x0419,  0x041A,  0x041B,  0x041C,  0x041D,  0x041E,  0x041F,
  0x0420,  0x0421,  0x0422,  0x0423,  0x0424,  0x0425,  0x0426,  0x0427,
  0x0428,  0x0429,  0x042A,  0x042B,  0x042C,  0x042D,  0x042E,  0x042F,
  0x0400,  0x0401,  0x0402,  0x0403,  0x0404,  0x0405,  0x0406,  0x0407,
  0x0408,  0x0409,  0x040A,  0x040B,  0x040C,  0x040D,  0x040E,  0x040F,
  0x0460,  0x0460,  0x0462,  0x0462,  0x0464,  0x0464,  0x0466,  0x0466,
  0x0468,  0x0468,  0x046A,  0x046A,  0x046C,  0x046C,  0x046E,  0x046E,
  0x0470,  0x0470,  0x0472,  0x0472,  0x0474,  0x0474,  0x0476,  0x0476,
  0x0478,  0x0478,  0x047A,  0x047A,  0x047C,  0x047C,  0x047E,  0x047E,
  0x0480,  0x0480,  0x0482,  0x0483,  0x0484,  0x0485,  0x0486,  0x0487,
  0x0488,  0x0489,  0x048A,  0x048B,  0x048C,  0x048C,  0x048E,  0x048E,
  0x0490,  0x0490,  0x0492,  0x0492,  0x0494,  0x0494,  0x0496,  0x0496,
  0x0498,  0x0498,  0x049A,  0x049A,  0x049C,  0x049C,  0x049E,  0x049E,
  0x04A0,  0x04A0,  0x04A2,  0x04A2,  0x04A4,  0x04A4,  0x04A6,  0x04A6,
  0x04A8,  0x04A8,  0x04AA,  0x04AA,  0x04AC,  0x04AC,  0x04AE,  0x04AE,
  0x04B0,  0x04B0,  0x04B2,  0x04B2,  0x04B4,  0x04B4,  0x04B6,  0x04B6,
  0x04B8,  0x04B8,  0x04BA,  0x04BA,  0x04BC,  0x04BC,  0x04BE,  0x04BE,
  0x04C0,  0x04C1,  0x04C1,  0x04C3,  0x04C3,  0x04C5,  0x04C6,  0x04C7,
  0x04C7,  0x04C9,  0x04CA,  0x04CB,  0x04CB,  0x04CD,  0x04CE,  0x04CF,
  0x04D0,  0x04D0,  0x04D2,  0x04D2,  0x04D4,  0x04D4,  0x04D6,  0x04D6,
  0x04D8,  0x04D8,  0x04DA,  0x04DA,  0x04DC,  0x04DC,  0x04DE,  0x04DE,
  0x04E0,  0x04E0,  0x04E2,  0x04E2,  0x04E4,  0x04E4,  0x04E6,  0x04E6,
  0x04E8,  0x04E8,  0x04EA,  0x04EA,  0x04EC,  0x04EC,  0x04EE,  0x04EE,
  0x04F0,  0x04F0,  0x04F2,  0x04F2,  0x04F4,  0x04F4,  0x04F6,  0x04F7,
  0x04F8,  0x04F8,  0x04FA,  0x04FB,  0x04FC,  0x04FD,  0x04FE,  0x04FF,
};

static uint32_t sort04[]={
  0x0415,  0x0415,  0x0402,  0x0413,  0x0404,  0x0405,  0x0406,  0x0406,
  0x0408,  0x0409,  0x040A,  0x040B,  0x041A,  0x0418,  0x0423,  0x040F,
  0x0410,  0x0411,  0x0412,  0x0413,  0x0414,  0x0415,  0x0416,  0x0417,
  0x0418,  0x0419,  0x041A,  0x041B,  0x041C,  0x041D,  0x041E,  0x041F,
  0x0420,  0x0421,  0x0422,  0x0423,  0x0424,  0x0425,  0x0426,  0x0427,
  0x0428,  0x0429,  0x042A,  0x042B,  0x042C,  0x042D,  0x042E,  0x042F,
  0x0410,  0x0411,  0x0412,  0x0413,  0x0414,  0x0415,  0x0416,  0x0417,
  0x0418,  0x0419,  0x041A,  0x041B,  0x041C,  0x041D,  0x041E,  0x041F,
  0x0420,  0x0421,  0x0422,  0x0423,  0x0424,  0x0425,  0x0426,  0x0427,
  0x0428,  0x0429,  0x042A,  0x042B,  0x042C,  0x042D,  0x042E,  0x042F,
  0x0415,  0x0415,  0x0402,  0x0413,  0x0404,  0x0405,  0x0406,  0x0406,
  0x0408,  0x0409,  0x040A,  0x040B,  0x041A,  0x0418,  0x0423,  0x040F,
  0x0460,  0x0460,  0x0462,  0x0462,  0x0464,  0x0464,  0x0466,  0x0466,
  0x0468,  0x0468,  0x046A,  0x046A,  0x046C,  0x046C,  0x046E,  0x046E,
  0x0470,  0x0470,  0x0472,  0x0472,  0x0474,  0x0474,  0x0474,  0x0474,
  0x0478,  0x0478,  0x047A,  0x047A,  0x047C,  0x047C,  0x047E,  0x047E,
  0x0480,  0x0480,  0x0482,  0x0483,  0x0484,  0x0485,  0x0486,  0x0487,
  0x0488,  0x0489,  0x048A,  0x048B,  0x048C,  0x048C,  0x048E,  0x048E,
  0x0490,  0x0490,  0x0492,  0x0492,  0x0494,  0x0494,  0x0496,  0x0496,
  0x0498,  0x0498,  0x049A,  0x049A,  0x049C,  0x049C,  0x049E,  0x049E,
  0x04A0,  0x04A0,  0x04A2,  0x04A2,  0x04A4,  0x04A4,  0x04A6,  0x04A6,
  0x04A8,  0x04A8,  0x04AA,  0x04AA,  0x04AC,  0x04AC,  0x04AE,  0x04AE,
  0x04B0,  0x04B0,  0x04B2,  0x04B2,  0x04B4,  0x04B4,  0x04B6,  0x04B6,
  0x04B8,  0x04B8,  0x04BA,  0x04BA,  0x04BC,  0x04BC,  0x04BE,  0x04BE,
  0x04C0,  0x0416,  0x0416,  0x04C3,  0x04C3,  0x04C5,  0x04C6,  0x04C7,
  0x04C7,  0x04C9,  0x04CA,  0x04CB,  0x04CB,  0x04CD,  0x04CE,  0x04CF,
  0x0410,  0x0410,  0x0410,  0x0410,  0x04D4,  0x04D4,  0x0415,  0x0415,
  0x04D8,  0x04D8,  0x04D8,  0x04D8,  0x0416,  0x0416,  0x0417,  0x0417,
  0x04E0,  0x04E0,  0x0418,  0x0418,  0x0418,  0x0418,  0x041E,  0x041E,
  0x04E8,  0x04E8,  0x04E8,  0x04E8,  0x042D,  0x042D,  0x0423,  0x0423,
  0x0423,  0x0423,  0x0423,  0x0423,  0x0427,  0x0427,  0x04F6,  0x04F7,
  0x042B,  0x042B,  0x04FA,  0x04FB,  0x04FC,  0x04FD,  0x04FE,  0x04FF,
};

static uint32_t lower05[]={
  0x0500,  0x0501,  0x0502,  0x0503,  0x0504,  0x0505,  0x0506,  0x0507,
  0x0508,  0x0509,  0x050A,  0x050B,  0x050C,  0x050D,  0x050E,  0x050F,
  0x0510,  0x0511,  0x0512,  0x0513,  0x0514,  0x0515,  0x0516,  0x0517,
  0x0518,  0x0519,  0x051A,  0x051B,  0x051C,  0x051D,  0x051E,  0x051F,
  0x0520,  0x0521,  0x0522,  0x0523,  0x0524,  0x0525,  0x0526,  0x0527,
  0x0528,  0x0529,  0x052A,  0x052B,  0x052C,  0x052D,  0x052E,  0x052F,
  0x0530,  0x0561,  0x0562,  0x0563,  0x0564,  0x0565,  0x0566,  0x0567,
  0x0568,  0x0569,  0x056A,  0x056B,  0x056C,  0x056D,  0x056E,  0x056F,
  0x0570,  0x0571,  0x0572,  0x0573,  0x0574,  0x0575,  0x0576,  0x0577,
  0x0578,  0x0579,  0x057A,  0x057B,  0x057C,  0x057D,  0x057E,  0x057F,
  0x0580,  0x0581,  0x0582,  0x0583,  0x0584,  0x0585,  0x0586,  0x0557,
  0x0558,  0x0559,  0x055A,  0x055B,  0x055C,  0x055D,  0x055E,  0x055F,
  0x0560,  0x0561,  0x0562,  0x0563,  0x0564,  0x0565,  0x0566,  0x0567,
  0x0568,  0x0569,  0x056A,  0x056B,  0x056C,  0x056D,  0x056E,  0x056F,
  0x0570,  0x0571,  0x0572,  0x0573,  0x0574,  0x0575,  0x0576,  0x0577,
  0x0578,  0x0579,  0x057A,  0x057B,  0x057C,  0x057D,  0x057E,  0x057F,
  0x0580,  0x0581,  0x0582,  0x0583,  0x0584,  0x0585,  0x0586,  0x0587,
  0x0588,  0x0589,  0x058A,  0x058B,  0x058C,  0x058D,  0x058E,  0x058F,
  0x0590,  0x0591,  0x0592,  0x0593,  0x0594,  0x0595,  0x0596,  0x0597,
  0x0598,  0x0599,  0x059A,  0x059B,  0x059C,  0x059D,  0x059E,  0x059F,
  0x05A0,  0x05A1,  0x05A2,  0x05A3,  0x05A4,  0x05A5,  0x05A6,  0x05A7,
  0x05A8,  0x05A9,  0x05AA,  0x05AB,  0x05AC,  0x05AD,  0x05AE,  0x05AF,
  0x05B0,  0x05B1,  0x05B2,  0x05B3,  0x05B4,  0x05B5,  0x05B6,  0x05B7,
  0x05B8,  0x05B9,  0x05BA,  0x05BB,  0x05BC,  0x05BD,  0x05BE,  0x05BF,
  0x05C0,  0x05C1,  0x05C2,  0x05C3,  0x05C4,  0x05C5,  0x05C6,  0x05C7,
  0x05C8,  0x05C9,  0x05CA,  0x05CB,  0x05CC,  0x05CD,  0x05CE,  0x05CF,
  0x05D0,  0x05D1,  0x05D2,  0x05D3,  0x05D4,  0x05D5,  0x05D6,  0x05D7,
  0x05D8,  0x05D9,  0x05DA,  0x05DB,  0x05DC,  0x05DD,  0x05DE,  0x05DF,
  0x05E0,  0x05E1,  0x05E2,  0x05E3,  0x05E4,  0x05E5,  0x05E6,  0x05E7,
  0x05E8,  0x05E9,  0x05EA,  0x05EB,  0x05EC,  0x05ED,  0x05EE,  0x05EF,
  0x05F0,  0x05F1,  0x05F2,  0x05F3,  0x05F4,  0x05F5,  0x05F6,  0x05F7,
  0x05F8,  0x05F9,  0x05FA,  0x05FB,  0x05FC,  0x05FD,  0x05FE,  0x05FF,
};

static uint32_t upper05[]={
  0x0500,  0x0501,  0x0502,  0x0503,  0x0504,  0x0505,  0x0506,  0x0507,
  0x0508,  0x0509,  0x050A,  0x050B,  0x050C,  0x050D,  0x050E,  0x050F,
  0x0510,  0x0511,  0x0512,  0x0513,  0x0514,  0x0515,  0x0516,  0x0517,
  0x0518,  0x0519,  0x051A,  0x051B,  0x051C,  0x051D,  0x051E,  0x051F,
  0x0520,  0x0521,  0x0522,  0x0523,  0x0524,  0x0525,  0x0526,  0x0527,
  0x0528,  0x0529,  0x052A,  0x052B,  0x052C,  0x052D,  0x052E,  0x052F,
  0x0530,  0x0531,  0x0532,  0x0533,  0x0534,  0x0535,  0x0536,  0x0537,
  0x0538,  0x0539,  0x053A,  0x053B,  0x053C,  0x053D,  0x053E,  0x053F,
  0x0540,  0x0541,  0x0542,  0x0543,  0x0544,  0x0545,  0x0546,  0x0547,
  0x0548,  0x0549,  0x054A,  0x054B,  0x054C,  0x054D,  0x054E,  0x054F,
  0x0550,  0x0551,  0x0552,  0x0553,  0x0554,  0x0555,  0x0556,  0x0557,
  0x0558,  0x0559,  0x055A,  0x055B,  0x055C,  0x055D,  0x055E,  0x055F,
  0x0560,  0x0531,  0x0532,  0x0533,  0x0534,  0x0535,  0x0536,  0x0537,
  0x0538,  0x0539,  0x053A,  0x053B,  0x053C,  0x053D,  0x053E,  0x053F,
  0x0540,  0x0541,  0x0542,  0x0543,  0x0544,  0x0545,  0x0546,  0x0547,
  0x0548,  0x0549,  0x054A,  0x054B,  0x054C,  0x054D,  0x054E,  0x054F,
  0x0550,  0x0551,  0x0552,  0x0553,  0x0554,  0x0555,  0x0556,  0x0587,
  0x0588,  0x0589,  0x058A,  0x058B,  0x058C,  0x058D,  0x058E,  0x058F,
  0x0590,  0x0591,  0x0592,  0x0593,  0x0594,  0x0595,  0x0596,  0x0597,
  0x0598,  0x0599,  0x059A,  0x059B,  0x059C,  0x059D,  0x059E,  0x059F,
  0x05A0,  0x05A1,  0x05A2,  0x05A3,  0x05A4,  0x05A5,  0x05A6,  0x05A7,
  0x05A8,  0x05A9,  0x05AA,  0x05AB,  0x05AC,  0x05AD,  0x05AE,  0x05AF,
  0x05B0,  0x05B1,  0x05B2,  0x05B3,  0x05B4,  0x05B5,  0x05B6,  0x05B7,
  0x05B8,  0x05B9,  0x05BA,  0x05BB,  0x05BC,  0x05BD,  0x05BE,  0x05BF,
  0x05C0,  0x05C1,  0x05C2,  0x05C3,  0x05C4,  0x05C5,  0x05C6,  0x05C7,
  0x05C8,  0x05C9,  0x05CA,  0x05CB,  0x05CC,  0x05CD,  0x05CE,  0x05CF,
  0x05D0,  0x05D1,  0x05D2,  0x05D3,  0x05D4,  0x05D5,  0x05D6,  0x05D7,
  0x05D8,  0x05D9,  0x05DA,  0x05DB,  0x05DC,  0x05DD,  0x05DE,  0x05DF,
  0x05E0,  0x05E1,  0x05E2,  0x05E3,  0x05E4,  0x05E5,  0x05E6,  0x05E7,
  0x05E8,  0x05E9,  0x05EA,  0x05EB,  0x05EC,  0x05ED,  0x05EE,  0x05EF,
  0x05F0,  0x05F1,  0x05F2,  0x05F3,  0x05F4,  0x05F5,  0x05F6,  0x05F7,
  0x05F8,  0x05F9,  0x05FA,  0x05FB,  0x05FC,  0x05FD,  0x05FE,  0x05FF,
};

static uint32_t sort05[]={
  0x0500,  0x0501,  0x0502,  0x0503,  0x0504,  0x0505,  0x0506,  0x0507,
  0x0508,  0x0509,  0x050A,  0x050B,  0x050C,  0x050D,  0x050E,  0x050F,
  0x0510,  0x0511,  0x0512,  0x0513,  0x0514,  0x0515,  0x0516,  0x0517,
  0x0518,  0x0519,  0x051A,  0x051B,  0x051C,  0x051D,  0x051E,  0x051F,
  0x0520,  0x0521,  0x0522,  0x0523,  0x0524,  0x0525,  0x0526,  0x0527,
  0x0528,  0x0529,  0x052A,  0x052B,  0x052C,  0x052D,  0x052E,  0x052F,
  0x0530,  0x0531,  0x0532,  0x0533,  0x0534,  0x0535,  0x0536,  0x0537,
  0x0538,  0x0539,  0x053A,  0x053B,  0x053C,  0x053D,  0x053E,  0x053F,
  0x0540,  0x0541,  0x0542,  0x0543,  0x0544,  0x0545,  0x0546,  0x0547,
  0x0548,  0x0549,  0x054A,  0x054B,  0x054C,  0x054D,  0x054E,  0x054F,
  0x0550,  0x0551,  0x0552,  0x0553,  0x0554,  0x0555,  0x0556,  0x0557,
  0x0558,  0x0559,  0x055A,  0x055B,  0x055C,  0x055D,  0x055E,  0x055F,
  0x0560,  0x0531,  0x0532,  0x0533,  0x0534,  0x0535,  0x0536,  0x0537,
  0x0538,  0x0539,  0x053A,  0x053B,  0x053C,  0x053D,  0x053E,  0x053F,
  0x0540,  0x0541,  0x0542,  0x0543,  0x0544,  0x0545,  0x0546,  0x0547,
  0x0548,  0x0549,  0x054A,  0x054B,  0x054C,  0x054D,  0x054E,  0x054F,
  0x0550,  0x0551,  0x0552,  0x0553,  0x0554,  0x0555,  0x0556,  0x0587,
  0x0588,  0x0589,  0x058A,  0x058B,  0x058C,  0x058D,  0x058E,  0x058F,
  0x0590,  0x0591,  0x0592,  0x0593,  0x0594,  0x0595,  0x0596,  0x0597,
  0x0598,  0x0599,  0x059A,  0x059B,  0x059C,  0x059D,  0x059E,  0x059F,
  0x05A0,  0x05A1,  0x05A2,  0x05A3,  0x05A4,  0x05A5,  0x05A6,  0x05A7,
  0x05A8,  0x05A9,  0x05AA,  0x05AB,  0x05AC,  0x05AD,  0x05AE,  0x05AF,
  0x05B0,  0x05B1,  0x05B2,  0x05B3,  0x05B4,  0x05B5,  0x05B6,  0x05B7,
  0x05B8,  0x05B9,  0x05BA,  0x05BB,  0x05BC,  0x05BD,  0x05BE,  0x05BF,
  0x05C0,  0x05C1,  0x05C2,  0x05C3,  0x05C4,  0x05C5,  0x05C6,  0x05C7,
  0x05C8,  0x05C9,  0x05CA,  0x05CB,  0x05CC,  0x05CD,  0x05CE,  0x05CF,
  0x05D0,  0x05D1,  0x05D2,  0x05D3,  0x05D4,  0x05D5,  0x05D6,  0x05D7,
  0x05D8,  0x05D9,  0x05DA,  0x05DB,  0x05DC,  0x05DD,  0x05DE,  0x05DF,
  0x05E0,  0x05E1,  0x05E2,  0x05E3,  0x05E4,  0x05E5,  0x05E6,  0x05E7,
  0x05E8,  0x05E9,  0x05EA,  0x05EB,  0x05EC,  0x05ED,  0x05EE,  0x05EF,
  0x05F0,  0x05F1,  0x05F2,  0x05F3,  0x05F4,  0x05F5,  0x05F6,  0x05F7,
  0x05F8,  0x05F9,  0x05FA,  0x05FB,  0x05FC,  0x05FD,  0x05FE,  0x05FF,
};

static uint32_t lower1E[]={
  0x1E01,  0x1E01,  0x1E03,  0x1E03,  0x1E05,  0x1E05,  0x1E07,  0x1E07,
  0x1E09,  0x1E09,  0x1E0B,  0x1E0B,  0x1E0D,  0x1E0D,  0x1E0F,  0x1E0F,
  0x1E11,  0x1E11,  0x1E13,  0x1E13,  0x1E15,  0x1E15,  0x1E17,  0x1E17,
  0x1E19,  0x1E19,  0x1E1B,  0x1E1B,  0x1E1D,  0x1E1D,  0x1E1F,  0x1E1F,
  0x1E21,  0x1E21,  0x1E23,  0x1E23,  0x1E25,  0x1E25,  0x1E27,  0x1E27,
  0x1E29,  0x1E29,  0x1E2B,  0x1E2B,  0x1E2D,  0x1E2D,  0x1E2F,  0x1E2F,
  0x1E31,  0x1E31,  0x1E33,  0x1E33,  0x1E35,  0x1E35,  0x1E37,  0x1E37,
  0x1E39,  0x1E39,  0x1E3B,  0x1E3B,  0x1E3D,  0x1E3D,  0x1E3F,  0x1E3F,
  0x1E41,  0x1E41,  0x1E43,  0x1E43,  0x1E45,  0x1E45,  0x1E47,  0x1E47,
  0x1E49,  0x1E49,  0x1E4B,  0x1E4B,  0x1E4D,  0x1E4D,  0x1E4F,  0x1E4F,
  0x1E51,  0x1E51,  0x1E53,  0x1E53,  0x1E55,  0x1E55,  0x1E57,  0x1E57,
  0x1E59,  0x1E59,  0x1E5B,  0x1E5B,  0x1E5D,  0x1E5D,  0x1E5F,  0x1E5F,
  0x1E61,  0x1E61,  0x1E63,  0x1E63,  0x1E65,  0x1E65,  0x1E67,  0x1E67,
  0x1E69,  0x1E69,  0x1E6B,  0x1E6B,  0x1E6D,  0x1E6D,  0x1E6F,  0x1E6F,
  0x1E71,  0x1E71,  0x1E73,  0x1E73,  0x1E75,  0x1E75,  0x1E77,  0x1E77,
  0x1E79,  0x1E79,  0x1E7B,  0x1E7B,  0x1E7D,  0x1E7D,  0x1E7F,  0x1E7F,
  0x1E81,  0x1E81,  0x1E83,  0x1E83,  0x1E85,  0x1E85,  0x1E87,  0x1E87,
  0x1E89,  0x1E89,  0x1E8B,  0x1E8B,  0x1E8D,  0x1E8D,  0x1E8F,  0x1E8F,
  0x1E91,  0x1E91,  0x1E93,  0x1E93,  0x1E95,  0x1E95,  0x1E96,  0x1E97,
  0x1E98,  0x1E99,  0x1E9A,  0x1E9B,  0x1E9C,  0x1E9D,  0x1E9E,  0x1E9F,
  0x1EA1,  0x1EA1,  0x1EA3,  0x1EA3,  0x1EA5,  0x1EA5,  0x1EA7,  0x1EA7,
  0x1EA9,  0x1EA9,  0x1EAB,  0x1EAB,  0x1EAD,  0x1EAD,  0x1EAF,  0x1EAF,
  0x1EB1,  0x1EB1,  0x1EB3,  0x1EB3,  0x1EB5,  0x1EB5,  0x1EB7,  0x1EB7,
  0x1EB9,  0x1EB9,  0x1EBB,  0x1EBB,  0x1EBD,  0x1EBD,  0x1EBF,  0x1EBF,
  0x1EC1,  0x1EC1,  0x1EC3,  0x1EC3,  0x1EC5,  0x1EC5,  0x1EC7,  0x1EC7,
  0x1EC9,  0x1EC9,  0x1ECB,  0x1ECB,  0x1ECD,  0x1ECD,  0x1ECF,  0x1ECF,
  0x1ED1,  0x1ED1,  0x1ED3,  0x1ED3,  0x1ED5,  0x1ED5,  0x1ED7,  0x1ED7,
  0x1ED9,  0x1ED9,  0x1EDB,  0x1EDB,  0x1EDD,  0x1EDD,  0x1EDF,  0x1EDF,
  0x1EE1,  0x1EE1,  0x1EE3,  0x1EE3,  0x1EE5,  0x1EE5,  0x1EE7,  0x1EE7,
  0x1EE9,  0x1EE9,  0x1EEB,  0x1EEB,  0x1EED,  0x1EED,  0x1EEF,  0x1EEF,
  0x1EF1,  0x1EF1,  0x1EF3,  0x1EF3,  0x1EF5,  0x1EF5,  0x1EF7,  0x1EF7,
  0x1EF9,  0x1EF9,  0x1EFA,  0x1EFB,  0x1EFC,  0x1EFD,  0x1EFE,  0x1EFF,
};

static uint32_t upper1E[]={
  0x1E00,  0x1E00,  0x1E02,  0x1E02,  0x1E04,  0x1E04,  0x1E06,  0x1E06,
  0x1E08,  0x1E08,  0x1E0A,  0x1E0A,  0x1E0C,  0x1E0C,  0x1E0E,  0x1E0E,
  0x1E10,  0x1E10,  0x1E12,  0x1E12,  0x1E14,  0x1E14,  0x1E16,  0x1E16,
  0x1E18,  0x1E18,  0x1E1A,  0x1E1A,  0x1E1C,  0x1E1C,  0x1E1E,  0x1E1E,
  0x1E20,  0x1E20,  0x1E22,  0x1E22,  0x1E24,  0x1E24,  0x1E26,  0x1E26,
  0x1E28,  0x1E28,  0x1E2A,  0x1E2A,  0x1E2C,  0x1E2C,  0x1E2E,  0x1E2E,
  0x1E30,  0x1E30,  0x1E32,  0x1E32,  0x1E34,  0x1E34,  0x1E36,  0x1E36,
  0x1E38,  0x1E38,  0x1E3A,  0x1E3A,  0x1E3C,  0x1E3C,  0x1E3E,  0x1E3E,
  0x1E40,  0x1E40,  0x1E42,  0x1E42,  0x1E44,  0x1E44,  0x1E46,  0x1E46,
  0x1E48,  0x1E48,  0x1E4A,  0x1E4A,  0x1E4C,  0x1E4C,  0x1E4E,  0x1E4E,
  0x1E50,  0x1E50,  0x1E52,  0x1E52,  0x1E54,  0x1E54,  0x1E56,  0x1E56,
  0x1E58,  0x1E58,  0x1E5A,  0x1E5A,  0x1E5C,  0x1E5C,  0x1E5E,  0x1E5E,
  0x1E60,  0x1E60,  0x1E62,  0x1E62,  0x1E64,  0x1E64,  0x1E66,  0x1E66,
  0x1E68,  0x1E68,  0x1E6A,  0x1E6A,  0x1E6C,  0x1E6C,  0x1E6E,  0x1E6E,
  0x1E70,  0x1E70,  0x1E72,  0x1E72,  0x1E74,  0x1E74,  0x1E76,  0x1E76,
  0x1E78,  0x1E78,  0x1E7A,  0x1E7A,  0x1E7C,  0x1E7C,  0x1E7E,  0x1E7E,
  0x1E80,  0x1E80,  0x1E82,  0x1E82,  0x1E84,  0x1E84,  0x1E86,  0x1E86,
  0x1E88,  0x1E88,  0x1E8A,  0x1E8A,  0x1E8C,  0x1E8C,  0x1E8E,  0x1E8E,
  0x1E90,  0x1E90,  0x1E92,  0x1E92,  0x1E94,  0x1E94,  0x1E96,  0x1E97,
  0x1E98,  0x1E99,  0x1E9A,  0x1E60,  0x1E9C,  0x1E9D,  0x1E9E,  0x1E9F,
  0x1EA0,  0x1EA0,  0x1EA2,  0x1EA2,  0x1EA4,  0x1EA4,  0x1EA6,  0x1EA6,
  0x1EA8,  0x1EA8,  0x1EAA,  0x1EAA,  0x1EAC,  0x1EAC,  0x1EAE,  0x1EAE,
  0x1EB0,  0x1EB0,  0x1EB2,  0x1EB2,  0x1EB4,  0x1EB4,  0x1EB6,  0x1EB6,
  0x1EB8,  0x1EB8,  0x1EBA,  0x1EBA,  0x1EBC,  0x1EBC,  0x1EBE,  0x1EBE,
  0x1EC0,  0x1EC0,  0x1EC2,  0x1EC2,  0x1EC4,  0x1EC4,  0x1EC6,  0x1EC6,
  0x1EC8,  0x1EC8,  0x1ECA,  0x1ECA,  0x1ECC,  0x1ECC,  0x1ECE,  0x1ECE,
  0x1ED0,  0x1ED0,  0x1ED2,  0x1ED2,  0x1ED4,  0x1ED4,  0x1ED6,  0x1ED6,
  0x1ED8,  0x1ED8,  0x1EDA,  0x1EDA,  0x1EDC,  0x1EDC,  0x1EDE,  0x1EDE,
  0x1EE0,  0x1EE0,  0x1EE2,  0x1EE2,  0x1EE4,  0x1EE4,  0x1EE6,  0x1EE6,
  0x1EE8,  0x1EE8,  0x1EEA,  0x1EEA,  0x1EEC,  0x1EEC,  0x1EEE,  0x1EEE,
  0x1EF0,  0x1EF0,  0x1EF2,  0x1EF2,  0x1EF4,  0x1EF4,  0x1EF6,  0x1EF6,
  0x1EF8,  0x1EF8,  0x1EFA,  0x1EFB,  0x1EFC,  0x1EFD,  0x1EFE,  0x1EFF,
};

static uint32_t sort1E[]={
  0x0041,  0x0041,  0x0042,  0x0042,  0x0042,  0x0042,  0x0042,  0x0042,
  0x0043,  0x0043,  0x0044,  0x0044,  0x0044,  0x0044,  0x0044,  0x0044,
  0x0044,  0x0044,  0x0044,  0x0044,  0x0045,  0x0045,  0x0045,  0x0045,
  0x0045,  0x0045,  0x0045,  0x0045,  0x0045,  0x0045,  0x0046,  0x0046,
  0x0047,  0x0047,  0x0048,  0x0048,  0x0048,  0x0048,  0x0048,  0x0048,
  0x0048,  0x0048,  0x0048,  0x0048,  0x0049,  0x0049,  0x0049,  0x0049,
  0x004B,  0x004B,  0x004B,  0x004B,  0x004B,  0x004B,  0x004C,  0x004C,
  0x004C,  0x004C,  0x004C,  0x004C,  0x004C,  0x004C,  0x004D,  0x004D,
  0x004D,  0x004D,  0x004D,  0x004D,  0x004E,  0x004E,  0x004E,  0x004E,
  0x004E,  0x004E,  0x004E,  0x004E,  0x004F,  0x004F,  0x004F,  0x004F,
  0x004F,  0x004F,  0x004F,  0x004F,  0x0050,  0x0050,  0x0050,  0x0050,
  0x0052,  0x0052,  0x0052,  0x0052,  0x0052,  0x0052,  0x0052,  0x0052,
  0x0053,  0x0053,  0x0053,  0x0053,  0x0053,  0x0053,  0x0053,  0x0053,
  0x0053,  0x0053,  0x0054,  0x0054,  0x0054,  0x0054,  0x0054,  0x0054,
  0x0054,  0x0054,  0x0055,  0x0055,  0x0055,  0x0055,  0x0055,  0x0055,
  0x0055,  0x0055,  0x0055,  0x0055,  0x0056,  0x0056,  0x0056,  0x0056,
  0x0057,  0x0057,  0x0057,  0x0057,  0x0057,  0x0057,  0x0057,  0x0057,
  0x0057,  0x0057,  0x0058,  0x0058,  0x0058,  0x0058,  0x0059,  0x0059,
  0x005A,  0x005A,  0x005A,  0x005A,  0x005A,  0x005A,  0x0048,  0x0054,
  0x0057,  0x0059,  0x1E9A,  0x0053,  0x1E9C,  0x1E9D,  0x1E9E,  0x1E9F,
  0x0041,  0x0041,  0x0041,  0x0041,  0x0041,  0x0041,  0x0041,  0x0041,
  0x0041,  0x0041,  0x0041,  0x0041,  0x0041,  0x0041,  0x0041,  0x0041,
  0x0041,  0x0041,  0x0041,  0x0041,  0x0041,  0x0041,  0x0041,  0x0041,
  0x0045,  0x0045,  0x0045,  0x0045,  0x0045,  0x0045,  0x0045,  0x0045,
  0x0045,  0x0045,  0x0045,  0x0045,  0x0045,  0x0045,  0x0045,  0x0045,
  0x0049,  0x0049,  0x0049,  0x0049,  0x004F,  0x004F,  0x004F,  0x004F,
  0x004F,  0x004F,  0x004F,  0x004F,  0x004F,  0x004F,  0x004F,  0x004F,
  0x004F,  0x004F,  0x004F,  0x004F,  0x004F,  0x004F,  0x004F,  0x004F,
  0x004F,  0x004F,  0x004F,  0x004F,  0x0055,  0x0055,  0x0055,  0x0055,
  0x0055,  0x0055,  0x0055,  0x0055,  0x0055,  0x0055,  0x0055,  0x0055,
  0x0055,  0x0055,  0x0059,  0x0059,  0x0059,  0x0059,  0x0059,  0x0059,
  0x0059,  0x0059,  0x1EFA,  0x1EFB,  0x1EFC,  0x1EFD,  0x1EFE,  0x1EFF,
};

static uint32_t lower1F[]={
  0x1F00,  0x1F01,  0x1F02,  0x1F03,  0x1F04,  0x1F05,  0x1F06,  0x1F07,
  0x1F00,  0x1F01,  0x1F02,  0x1F03,  0x1F04,  0x1F05,  0x1F06,  0x1F07,
  0x1F10,  0x1F11,  0x1F12,  0x1F13,  0x1F14,  0x1F15,  0x1F16,  0x1F17,
  0x1F10,  0x1F11,  0x1F12,  0x1F13,  0x1F14,  0x1F15,  0x1F1E,  0x1F1F,
  0x1F20,  0x1F21,  0x1F22,  0x1F23,  0x1F24,  0x1F25,  0x1F26,  0x1F27,
  0x1F20,  0x1F21,  0x1F22,  0x1F23,  0x1F24,  0x1F25,  0x1F26,  0x1F27,
  0x1F30,  0x1F31,  0x1F32,  0x1F33,  0x1F34,  0x1F35,  0x1F36,  0x1F37,
  0x1F30,  0x1F31,  0x1F32,  0x1F33,  0x1F34,  0x1F35,  0x1F36,  0x1F37,
  0x1F40,  0x1F41,  0x1F42,  0x1F43,  0x1F44,  0x1F45,  0x1F46,  0x1F47,
  0x1F40,  0x1F41,  0x1F42,  0x1F43,  0x1F44,  0x1F45,  0x1F4E,  0x1F4F,
  0x1F50,  0x1F51,  0x1F52,  0x1F53,  0x1F54,  0x1F55,  0x1F56,  0x1F57,
  0x1F58,  0x1F51,  0x1F5A,  0x1F53,  0x1F5C,  0x1F55,  0x1F5E,  0x1F57,
  0x1F60,  0x1F61,  0x1F62,  0x1F63,  0x1F64,  0x1F65,  0x1F66,  0x1F67,
  0x1F60,  0x1F61,  0x1F62,  0x1F63,  0x1F64,  0x1F65,  0x1F66,  0x1F67,
  0x1F70,  0x1F71,  0x1F72,  0x1F73,  0x1F74,  0x1F75,  0x1F76,  0x1F77,
  0x1F78,  0x1F79,  0x1F7A,  0x1F7B,  0x1F7C,  0x1F7D,  0x1F7E,  0x1F7F,
  0x1F80,  0x1F81,  0x1F82,  0x1F83,  0x1F84,  0x1F85,  0x1F86,  0x1F87,
  0x1F80,  0x1F81,  0x1F82,  0x1F83,  0x1F84,  0x1F85,  0x1F86,  0x1F87,
  0x1F90,  0x1F91,  0x1F92,  0x1F93,  0x1F94,  0x1F95,  0x1F96,  0x1F97,
  0x1F90,  0x1F91,  0x1F92,  0x1F93,  0x1F94,  0x1F95,  0x1F96,  0x1F97,
  0x1FA0,  0x1FA1,  0x1FA2,  0x1FA3,  0x1FA4,  0x1FA5,  0x1FA6,  0x1FA7,
  0x1FA0,  0x1FA1,  0x1FA2,  0x1FA3,  0x1FA4,  0x1FA5,  0x1FA6,  0x1FA7,
  0x1FB0,  0x1FB1,  0x1FB2,  0x1FB3,  0x1FB4,  0x1FB5,  0x1FB6,  0x1FB7,
  0x1FB0,  0x1FB1,  0x1F70,  0x1F71,  0x1FB3,  0x1FBD,  0x1FBE,  0x1FBF,
  0x1FC0,  0x1FC1,  0x1FC2,  0x1FC3,  0x1FC4,  0x1FC5,  0x1FC6,  0x1FC7,
  0x1F72,  0x1F73,  0x1F74,  0x1F75,  0x1FC3,  0x1FCD,  0x1FCE,  0x1FCF,
  0x1FD0,  0x1FD1,  0x1FD2,  0x1FD3,  0x1FD4,  0x1FD5,  0x1FD6,  0x1FD7,
  0x1FD0,  0x1FD1,  0x1F76,  0x1F77,  0x1FDC,  0x1FDD,  0x1FDE,  0x1FDF,
  0x1FE0,  0x1FE1,  0x1FE2,  0x1FE3,  0x1FE4,  0x1FE5,  0x1FE6,  0x1FE7,
  0x1FE0,  0x1FE1,  0x1F7A,  0x1F7B,  0x1FE5,  0x1FED,  0x1FEE,  0x1FEF,
  0x1FF0,  0x1FF1,  0x1FF2,  0x1FF3,  0x1FF4,  0x1FF5,  0x1FF6,  0x1FF7,
  0x1F78,  0x1F79,  0x1F7C,  0x1F7D,  0x1FF3,  0x1FFD,  0x1FFE,  0x1FFF,
};

static uint32_t upper1F[]={
  0x1F08,  0x1F09,  0x1F0A,  0x1F0B,  0x1F0C,  0x1F0D,  0x1F0E,  0x1F0F,
  0x1F08,  0x1F09,  0x1F0A,  0x1F0B,  0x1F0C,  0x1F0D,  0x1F0E,  0x1F0F,
  0x1F18,  0x1F19,  0x1F1A,  0x1F1B,  0x1F1C,  0x1F1D,  0x1F16,  0x1F17,
  0x1F18,  0x1F19,  0x1F1A,  0x1F1B,  0x1F1C,  0x1F1D,  0x1F1E,  0x1F1F,
  0x1F28,  0x1F29,  0x1F2A,  0x1F2B,  0x1F2C,  0x1F2D,  0x1F2E,  0x1F2F,
  0x1F28,  0x1F29,  0x1F2A,  0x1F2B,  0x1F2C,  0x1F2D,  0x1F2E,  0x1F2F,
  0x1F38,  0x1F39,  0x1F3A,  0x1F3B,  0x1F3C,  0x1F3D,  0x1F3E,  0x1F3F,
  0x1F38,  0x1F39,  0x1F3A,  0x1F3B,  0x1F3C,  0x1F3D,  0x1F3E,  0x1F3F,
  0x1F48,  0x1F49,  0x1F4A,  0x1F4B,  0x1F4C,  0x1F4D,  0x1F46,  0x1F47,
  0x1F48,  0x1F49,  0x1F4A,  0x1F4B,  0x1F4C,  0x1F4D,  0x1F4E,  0x1F4F,
  0x1F50,  0x1F59,  0x1F52,  0x1F5B,  0x1F54,  0x1F5D,  0x1F56,  0x1F5F,
  0x1F58,  0x1F59,  0x1F5A,  0x1F5B,  0x1F5C,  0x1F5D,  0x1F5E,  0x1F5F,
  0x1F68,  0x1F69,  0x1F6A,  0x1F6B,  0x1F6C,  0x1F6D,  0x1F6E,  0x1F6F,
  0x1F68,  0x1F69,  0x1F6A,  0x1F6B,  0x1F6C,  0x1F6D,  0x1F6E,  0x1F6F,
  0x1FBA,  0x1FBB,  0x1FC8,  0x1FC9,  0x1FCA,  0x1FCB,  0x1FDA,  0x1FDB,
  0x1FF8,  0x1FF9,  0x1FEA,  0x1FEB,  0x1FFA,  0x1FFB,  0x1F7E,  0x1F7F,
  0x1F88,  0x1F89,  0x1F8A,  0x1F8B,  0x1F8C,  0x1F8D,  0x1F8E,  0x1F8F,
  0x1F88,  0x1F89,  0x1F8A,  0x1F8B,  0x1F8C,  0x1F8D,  0x1F8E,  0x1F8F,
  0x1F98,  0x1F99,  0x1F9A,  0x1F9B,  0x1F9C,  0x1F9D,  0x1F9E,  0x1F9F,
  0x1F98,  0x1F99,  0x1F9A,  0x1F9B,  0x1F9C,  0x1F9D,  0x1F9E,  0x1F9F,
  0x1FA8,  0x1FA9,  0x1FAA,  0x1FAB,  0x1FAC,  0x1FAD,  0x1FAE,  0x1FAF,
  0x1FA8,  0x1FA9,  0x1FAA,  0x1FAB,  0x1FAC,  0x1FAD,  0x1FAE,  0x1FAF,
  0x1FB8,  0x1FB9,  0x1FB2,  0x1FBC,  0x1FB4,  0x1FB5,  0x1FB6,  0x1FB7,
  0x1FB8,  0x1FB9,  0x1FBA,  0x1FBB,  0x1FBC,  0x1FBD,  0x0399,  0x1FBF,
  0x1FC0,  0x1FC1,  0x1FC2,  0x1FCC,  0x1FC4,  0x1FC5,  0x1FC6,  0x1FC7,
  0x1FC8,  0x1FC9,  0x1FCA,  0x1FCB,  0x1FCC,  0x1FCD,  0x1FCE,  0x1FCF,
  0x1FD8,  0x1FD9,  0x1FD2,  0x1FD3,  0x1FD4,  0x1FD5,  0x1FD6,  0x1FD7,
  0x1FD8,  0x1FD9,  0x1FDA,  0x1FDB,  0x1FDC,  0x1FDD,  0x1FDE,  0x1FDF,
  0x1FE8,  0x1FE9,  0x1FE2,  0x1FE3,  0x1FE4,  0x1FEC,  0x1FE6,  0x1FE7,
  0x1FE8,  0x1FE9,  0x1FEA,  0x1FEB,  0x1FEC,  0x1FED,  0x1FEE,  0x1FEF,
  0x1FF0,  0x1FF1,  0x1FF2,  0x1FFC,  0x1FF4,  0x1FF5,  0x1FF6,  0x1FF7,
  0x1FF8,  0x1FF9,  0x1FFA,  0x1FFB,  0x1FFC,  0x1FFD,  0x1FFE,  0x1FFF,
};

static uint32_t sort1F[]={
  0x0391,  0x0391,  0x0391,  0x0391,  0x0391,  0x0391,  0x0391,  0x0391,
  0x0391,  0x0391,  0x0391,  0x0391,  0x0391,  0x0391,  0x0391,  0x0391,
  0x0395,  0x0395,  0x0395,  0x0395,  0x0395,  0x0395,  0x1F16,  0x1F17,
  0x0395,  0x0395,  0x0395,  0x0395,  0x0395,  0x0395,  0x1F1E,  0x1F1F,
  0x0397,  0x0397,  0x0397,  0x0397,  0x0397,  0x0397,  0x0397,  0x0397,
  0x0397,  0x0397,  0x0397,  0x0397,  0x0397,  0x0397,  0x0397,  0x0397,
  0x0399,  0x0399,  0x0399,  0x0399,  0x0399,  0x0399,  0x0399,  0x0399,
  0x0399,  0x0399,  0x0399,  0x0399,  0x0399,  0x0399,  0x0399,  0x0399,
  0x039F,  0x039F,  0x039F,  0x039F,  0x039F,  0x039F,  0x1F46,  0x1F47,
  0x039F,  0x039F,  0x039F,  0x039F,  0x039F,  0x039F,  0x1F4E,  0x1F4F,
  0x03A5,  0x03A5,  0x03A5,  0x03A5,  0x03A5,  0x03A5,  0x03A5,  0x03A5,
  0x1F58,  0x03A5,  0x1F5A,  0x03A5,  0x1F5C,  0x03A5,  0x1F5E,  0x03A5,
  0x03A9,  0x03A9,  0x03A9,  0x03A9,  0x03A9,  0x03A9,  0x03A9,  0x03A9,
  0x03A9,  0x03A9,  0x03A9,  0x03A9,  0x03A9,  0x03A9,  0x03A9,  0x03A9,
  0x0391,  0x1FBB,  0x0395,  0x1FC9,  0x0397,  0x1FCB,  0x0399,  0x1FDB,
  0x039F,  0x1FF9,  0x03A5,  0x1FEB,  0x03A9,  0x1FFB,  0x1F7E,  0x1F7F,
  0x0391,  0x0391,  0x0391,  0x0391,  0x0391,  0x0391,  0x0391,  0x0391,
  0x0391,  0x0391,  0x0391,  0x0391,  0x0391,  0x0391,  0x0391,  0x0391,
  0x0397,  0x0397,  0x0397,  0x0397,  0x0397,  0x0397,  0x0397,  0x0397,
  0x0397,  0x0397,  0x0397,  0x0397,  0x0397,  0x0397,  0x0397,  0x0397,
  0x03A9,  0x03A9,  0x03A9,  0x03A9,  0x03A9,  0x03A9,  0x03A9,  0x03A9,
  0x03A9,  0x03A9,  0x03A9,  0x03A9,  0x03A9,  0x03A9,  0x03A9,  0x03A9,
  0x0391,  0x0391,  0x0391,  0x0391,  0x0391,  0x1FB5,  0x0391,  0x0391,
  0x0391,  0x0391,  0x0391,  0x1FBB,  0x0391,  0x1FBD,  0x0399,  0x1FBF,
  0x1FC0,  0x1FC1,  0x0397,  0x0397,  0x0397,  0x1FC5,  0x0397,  0x0397,
  0x0395,  0x1FC9,  0x0397,  0x1FCB,  0x0397,  0x1FCD,  0x1FCE,  0x1FCF,
  0x0399,  0x0399,  0x0399,  0x1FD3,  0x1FD4,  0x1FD5,  0x0399,  0x0399,
  0x0399,  0x0399,  0x0399,  0x1FDB,  0x1FDC,  0x1FDD,  0x1FDE,  0x1FDF,
  0x03A5,  0x03A5,  0x03A5,  0x1FE3,  0x03A1,  0x03A1,  0x03A5,  0x03A5,
  0x03A5,  0x03A5,  0x03A5,  0x1FEB,  0x03A1,  0x1FED,  0x1FEE,  0x1FEF,
  0x1FF0,  0x1FF1,  0x03A9,  0x03A9,  0x03A9,  0x1FF5,  0x03A9,  0x03A9,
  0x039F,  0x1FF9,  0x03A9,  0x1FFB,  0x03A9,  0x1FFD,  0x1FFE,  0x1FFF,
};

static uint32_t lower21[]={
  0x2100,  0x2101,  0x2102,  0x2103,  0x2104,  0x2105,  0x2106,  0x2107,
  0x2108,  0x2109,  0x210A,  0x210B,  0x210C,  0x210D,  0x210E,  0x210F,
  0x2110,  0x2111,  0x2112,  0x2113,  0x2114,  0x2115,  0x2116,  0x2117,
  0x2118,  0x2119,  0x211A,  0x211B,  0x211C,  0x211D,  0x211E,  0x211F,
  0x2120,  0x2121,  0x2122,  0x2123,  0x2124,  0x2125,  0x03C9,  0x2127,
  0x2128,  0x2129,  0x006B,  0x00E5,  0x212C,  0x212D,  0x212E,  0x212F,
  0x2130,  0x2131,  0x2132,  0x2133,  0x2134,  0x2135,  0x2136,  0x2137,
  0x2138,  0x2139,  0x213A,  0x213B,  0x213C,  0x213D,  0x213E,  0x213F,
  0x2140,  0x2141,  0x2142,  0x2143,  0x2144,  0x2145,  0x2146,  0x2147,
  0x2148,  0x2149,  0x214A,  0x214B,  0x214C,  0x214D,  0x214E,  0x214F,
  0x2150,  0x2151,  0x2152,  0x2153,  0x2154,  0x2155,  0x2156,  0x2157,
  0x2158,  0x2159,  0x215A,  0x215B,  0x215C,  0x215D,  0x215E,  0x215F,
  0x2170,  0x2171,  0x2172,  0x2173,  0x2174,  0x2175,  0x2176,  0x2177,
  0x2178,  0x2179,  0x217A,  0x217B,  0x217C,  0x217D,  0x217E,  0x217F,
  0x2170,  0x2171,  0x2172,  0x2173,  0x2174,  0x2175,  0x2176,  0x2177,
  0x2178,  0x2179,  0x217A,  0x217B,  0x217C,  0x217D,  0x217E,  0x217F,
  0x2180,  0x2181,  0x2182,  0x2183,  0x2184,  0x2185,  0x2186,  0x2187,
  0x2188,  0x2189,  0x218A,  0x218B,  0x218C,  0x218D,  0x218E,  0x218F,
  0x2190,  0x2191,  0x2192,  0x2193,  0x2194,  0x2195,  0x2196,  0x2197,
  0x2198,  0x2199,  0x219A,  0x219B,  0x219C,  0x219D,  0x219E,  0x219F,
  0x21A0,  0x21A1,  0x21A2,  0x21A3,  0x21A4,  0x21A5,  0x21A6,  0x21A7,
  0x21A8,  0x21A9,  0x21AA,  0x21AB,  0x21AC,  0x21AD,  0x21AE,  0x21AF,
  0x21B0,  0x21B1,  0x21B2,  0x21B3,  0x21B4,  0x21B5,  0x21B6,  0x21B7,
  0x21B8,  0x21B9,  0x21BA,  0x21BB,  0x21BC,  0x21BD,  0x21BE,  0x21BF,
  0x21C0,  0x21C1,  0x21C2,  0x21C3,  0x21C4,  0x21C5,  0x21C6,  0x21C7,
  0x21C8,  0x21C9,  0x21CA,  0x21CB,  0x21CC,  0x21CD,  0x21CE,  0x21CF,
  0x21D0,  0x21D1,  0x21D2,  0x21D3,  0x21D4,  0x21D5,  0x21D6,  0x21D7,
  0x21D8,  0x21D9,  0x21DA,  0x21DB,  0x21DC,  0x21DD,  0x21DE,  0x21DF,
  0x21E0,  0x21E1,  0x21E2,  0x21E3,  0x21E4,  0x21E5,  0x21E6,  0x21E7,
  0x21E8,  0x21E9,  0x21EA,  0x21EB,  0x21EC,  0x21ED,  0x21EE,  0x21EF,
  0x21F0,  0x21F1,  0x21F2,  0x21F3,  0x21F4,  0x21F5,  0x21F6,  0x21F7,
  0x21F8,  0x21F9,  0x21FA,  0x21FB,  0x21FC,  0x21FD,  0x21FE,  0x21FF,
};

static uint32_t upper21[]={
  0x2100,  0x2101,  0x2102,  0x2103,  0x2104,  0x2105,  0x2106,  0x2107,
  0x2108,  0x2109,  0x210A,  0x210B,  0x210C,  0x210D,  0x210E,  0x210F,
  0x2110,  0x2111,  0x2112,  0x2113,  0x2114,  0x2115,  0x2116,  0x2117,
  0x2118,  0x2119,  0x211A,  0x211B,  0x211C,  0x211D,  0x211E,  0x211F,
  0x2120,  0x2121,  0x2122,  0x2123,  0x2124,  0x2125,  0x2126,  0x2127,
  0x2128,  0x2129,  0x212A,  0x212B,  0x212C,  0x212D,  0x212E,  0x212F,
  0x2130,  0x2131,  0x2132,  0x2133,  0x2134,  0x2135,  0x2136,  0x2137,
  0x2138,  0x2139,  0x213A,  0x213B,  0x213C,  0x213D,  0x213E,  0x213F,
  0x2140,  0x2141,  0x2142,  0x2143,  0x2144,  0x2145,  0x2146,  0x2147,
  0x2148,  0x2149,  0x214A,  0x214B,  0x214C,  0x214D,  0x214E,  0x214F,
  0x2150,  0x2151,  0x2152,  0x2153,  0x2154,  0x2155,  0x2156,  0x2157,
  0x2158,  0x2159,  0x215A,  0x215B,  0x215C,  0x215D,  0x215E,  0x215F,
  0x2160,  0x2161,  0x2162,  0x2163,  0x2164,  0x2165,  0x2166,  0x2167,
  0x2168,  0x2169,  0x216A,  0x216B,  0x216C,  0x216D,  0x216E,  0x216F,
  0x2160,  0x2161,  0x2162,  0x2163,  0x2164,  0x2165,  0x2166,  0x2167,
  0x2168,  0x2169,  0x216A,  0x216B,  0x216C,  0x216D,  0x216E,  0x216F,
  0x2180,  0x2181,  0x2182,  0x2183,  0x2184,  0x2185,  0x2186,  0x2187,
  0x2188,  0x2189,  0x218A,  0x218B,  0x218C,  0x218D,  0x218E,  0x218F,
  0x2190,  0x2191,  0x2192,  0x2193,  0x2194,  0x2195,  0x2196,  0x2197,
  0x2198,  0x2199,  0x219A,  0x219B,  0x219C,  0x219D,  0x219E,  0x219F,
  0x21A0,  0x21A1,  0x21A2,  0x21A3,  0x21A4,  0x21A5,  0x21A6,  0x21A7,
  0x21A8,  0x21A9,  0x21AA,  0x21AB,  0x21AC,  0x21AD,  0x21AE,  0x21AF,
  0x21B0,  0x21B1,  0x21B2,  0x21B3,  0x21B4,  0x21B5,  0x21B6,  0x21B7,
  0x21B8,  0x21B9,  0x21BA,  0x21BB,  0x21BC,  0x21BD,  0x21BE,  0x21BF,
  0x21C0,  0x21C1,  0x21C2,  0x21C3,  0x21C4,  0x21C5,  0x21C6,  0x21C7,
  0x21C8,  0x21C9,  0x21CA,  0x21CB,  0x21CC,  0x21CD,  0x21CE,  0x21CF,
  0x21D0,  0x21D1,  0x21D2,  0x21D3,  0x21D4,  0x21D5,  0x21D6,  0x21D7,
  0x21D8,  0x21D9,  0x21DA,  0x21DB,  0x21DC,  0x21DD,  0x21DE,  0x21DF,
  0x21E0,  0x21E1,  0x21E2,  0x21E3,  0x21E4,  0x21E5,  0x21E6,  0x21E7,
  0x21E8,  0x21E9,  0x21EA,  0x21EB,  0x21EC,  0x21ED,  0x21EE,  0x21EF,
  0x21F0,  0x21F1,  0x21F2,  0x21F3,  0x21F4,  0x21F5,  0x21F6,  0x21F7,
  0x21F8,  0x21F9,  0x21FA,  0x21FB,  0x21FC,  0x21FD,  0x21FE,  0x21FF,
};

static uint32_t sort21[]={
  0x2100,  0x2101,  0x2102,  0x2103,  0x2104,  0x2105,  0x2106,  0x2107,
  0x2108,  0x2109,  0x210A,  0x210B,  0x210C,  0x210D,  0x210E,  0x210F,
  0x2110,  0x2111,  0x2112,  0x2113,  0x2114,  0x2115,  0x2116,  0x2117,
  0x2118,  0x2119,  0x211A,  0x211B,  0x211C,  0x211D,  0x211E,  0x211F,
  0x2120,  0x2121,  0x2122,  0x2123,  0x2124,  0x2125,  0x2126,  0x2127,
  0x2128,  0x2129,  0x212A,  0x212B,  0x212C,  0x212D,  0x212E,  0x212F,
  0x2130,  0x2131,  0x2132,  0x2133,  0x2134,  0x2135,  0x2136,  0x2137,
  0x2138,  0x2139,  0x213A,  0x213B,  0x213C,  0x213D,  0x213E,  0x213F,
  0x2140,  0x2141,  0x2142,  0x2143,  0x2144,  0x2145,  0x2146,  0x2147,
  0x2148,  0x2149,  0x214A,  0x214B,  0x214C,  0x214D,  0x214E,  0x214F,
  0x2150,  0x2151,  0x2152,  0x2153,  0x2154,  0x2155,  0x2156,  0x2157,
  0x2158,  0x2159,  0x215A,  0x215B,  0x215C,  0x215D,  0x215E,  0x215F,
  0x2160,  0x2161,  0x2162,  0x2163,  0x2164,  0x2165,  0x2166,  0x2167,
  0x2168,  0x2169,  0x216A,  0x216B,  0x216C,  0x216D,  0x216E,  0x216F,
  0x2160,  0x2161,  0x2162,  0x2163,  0x2164,  0x2165,  0x2166,  0x2167,
  0x2168,  0x2169,  0x216A,  0x216B,  0x216C,  0x216D,  0x216E,  0x216F,
  0x2180,  0x2181,  0x2182,  0x2183,  0x2184,  0x2185,  0x2186,  0x2187,
  0x2188,  0x2189,  0x218A,  0x218B,  0x218C,  0x218D,  0x218E,  0x218F,
  0x2190,  0x2191,  0x2192,  0x2193,  0x2194,  0x2195,  0x2196,  0x2197,
  0x2198,  0x2199,  0x219A,  0x219B,  0x219C,  0x219D,  0x219E,  0x219F,
  0x21A0,  0x21A1,  0x21A2,  0x21A3,  0x21A4,  0x21A5,  0x21A6,  0x21A7,
  0x21A8,  0x21A9,  0x21AA,  0x21AB,  0x21AC,  0x21AD,  0x21AE,  0x21AF,
  0x21B0,  0x21B1,  0x21B2,  0x21B3,  0x21B4,  0x21B5,  0x21B6,  0x21B7,
  0x21B8,  0x21B9,  0x21BA,  0x21BB,  0x21BC,  0x21BD,  0x21BE,  0x21BF,
  0x21C0,  0x21C1,  0x21C2,  0x21C3,  0x21C4,  0x21C5,  0x21C6,  0x21C7,
  0x21C8,  0x21C9,  0x21CA,  0x21CB,  0x21CC,  0x21CD,  0x21CE,  0x21CF,
  0x21D0,  0x21D1,  0x21D2,  0x21D3,  0x21D4,  0x21D5,  0x21D6,  0x21D7,
  0x21D8,  0x21D9,  0x21DA,  0x21DB,  0x21DC,  0x21DD,  0x21DE,  0x21DF,
  0x21E0,  0x21E1,  0x21E2,  0x21E3,  0x21E4,  0x21E5,  0x21E6,  0x21E7,
  0x21E8,  0x21E9,  0x21EA,  0x21EB,  0x21EC,  0x21ED,  0x21EE,  0x21EF,
  0x21F0,  0x21F1,  0x21F2,  0x21F3,  0x21F4,  0x21F5,  0x21F6,  0x21F7,
  0x21F8,  0x21F9,  0x21FA,  0x21FB,  0x21FC,  0x21FD,  0x21FE,  0x21FF,
};

static uint32_t lower24[]={
  0x2400,  0x2401,  0x2402,  0x2403,  0x2404,  0x2405,  0x2406,  0x2407,
  0x2408,  0x2409,  0x240A,  0x240B,  0x240C,  0x240D,  0x240E,  0x240F,
  0x2410,  0x2411,  0x2412,  0x2413,  0x2414,  0x2415,  0x2416,  0x2417,
  0x2418,  0x2419,  0x241A,  0x241B,  0x241C,  0x241D,  0x241E,  0x241F,
  0x2420,  0x2421,  0x2422,  0x2423,  0x2424,  0x2425,  0x2426,  0x2427,
  0x2428,  0x2429,  0x242A,  0x242B,  0x242C,  0x242D,  0x242E,  0x242F,
  0x2430,  0x2431,  0x2432,  0x2433,  0x2434,  0x2435,  0x2436,  0x2437,
  0x2438,  0x2439,  0x243A,  0x243B,  0x243C,  0x243D,  0x243E,  0x243F,
  0x2440,  0x2441,  0x2442,  0x2443,  0x2444,  0x2445,  0x2446,  0x2447,
  0x2448,  0x2449,  0x244A,  0x244B,  0x244C,  0x244D,  0x244E,  0x244F,
  0x2450,  0x2451,  0x2452,  0x2453,  0x2454,  0x2455,  0x2456,  0x2457,
  0x2458,  0x2459,  0x245A,  0x245B,  0x245C,  0x245D,  0x245E,  0x245F,
  0x2460,  0x2461,  0x2462,  0x2463,  0x2464,  0x2465,  0x2466,  0x2467,
  0x2468,  0x2469,  0x246A,  0x246B,  0x246C,  0x246D,  0x246E,  0x246F,
  0x2470,  0x2471,  0x2472,  0x2473,  0x2474,  0x2475,  0x2476,  0x2477,
  0x2478,  0x2479,  0x247A,  0x247B,  0x247C,  0x247D,  0x247E,  0x247F,
  0x2480,  0x2481,  0x2482,  0x2483,  0x2484,  0x2485,  0x2486,  0x2487,
  0x2488,  0x2489,  0x248A,  0x248B,  0x248C,  0x248D,  0x248E,  0x248F,
  0x2490,  0x2491,  0x2492,  0x2493,  0x2494,  0x2495,  0x2496,  0x2497,
  0x2498,  0x2499,  0x249A,  0x249B,  0x249C,  0x249D,  0x249E,  0x249F,
  0x24A0,  0x24A1,  0x24A2,  0x24A3,  0x24A4,  0x24A5,  0x24A6,  0x24A7,
  0x24A8,  0x24A9,  0x24AA,  0x24AB,  0x24AC,  0x24AD,  0x24AE,  0x24AF,
  0x24B0,  0x24B1,  0x24B2,  0x24B3,  0x24B4,  0x24B5,  0x24D0,  0x24D1,
  0x24D2,  0x24D3,  0x24D4,  0x24D5,  0x24D6,  0x24D7,  0x24D8,  0x24D9,
  0x24DA,  0x24DB,  0x24DC,  0x24DD,  0x24DE,  0x24DF,  0x24E0,  0x24E1,
  0x24E2,  0x24E3,  0x24E4,  0x24E5,  0x24E6,  0x24E7,  0x24E8,  0x24E9,
  0x24D0,  0x24D1,  0x24D2,  0x24D3,  0x24D4,  0x24D5,  0x24D6,  0x24D7,
  0x24D8,  0x24D9,  0x24DA,  0x24DB,  0x24DC,  0x24DD,  0x24DE,  0x24DF,
  0x24E0,  0x24E1,  0x24E2,  0x24E3,  0x24E4,  0x24E5,  0x24E6,  0x24E7,
  0x24E8,  0x24E9,  0x24EA,  0x24EB,  0x24EC,  0x24ED,  0x24EE,  0x24EF,
  0x24F0,  0x24F1,  0x24F2,  0x24F3,  0x24F4,  0x24F5,  0x24F6,  0x24F7,
  0x24F8,  0x24F9,  0x24FA,  0x24FB,  0x24FC,  0x24FD,  0x24FE,  0x24FF,
};

static uint32_t upper24[]={
  0x2400,  0x2401,  0x2402,  0x2403,  0x2404,  0x2405,  0x2406,  0x2407,
  0x2408,  0x2409,  0x240A,  0x240B,  0x240C,  0x240D,  0x240E,  0x240F,
  0x2410,  0x2411,  0x2412,  0x2413,  0x2414,  0x2415,  0x2416,  0x2417,
  0x2418,  0x2419,  0x241A,  0x241B,  0x241C,  0x241D,  0x241E,  0x241F,
  0x2420,  0x2421,  0x2422,  0x2423,  0x2424,  0x2425,  0x2426,  0x2427,
  0x2428,  0x2429,  0x242A,  0x242B,  0x242C,  0x242D,  0x242E,  0x242F,
  0x2430,  0x2431,  0x2432,  0x2433,  0x2434,  0x2435,  0x2436,  0x2437,
  0x2438,  0x2439,  0x243A,  0x243B,  0x243C,  0x243D,  0x243E,  0x243F,
  0x2440,  0x2441,  0x2442,  0x2443,  0x2444,  0x2445,  0x2446,  0x2447,
  0x2448,  0x2449,  0x244A,  0x244B,  0x244C,  0x244D,  0x244E,  0x244F,
  0x2450,  0x2451,  0x2452,  0x2453,  0x2454,  0x2455,  0x2456,  0x2457,
  0x2458,  0x2459,  0x245A,  0x245B,  0x245C,  0x245D,  0x245E,  0x245F,
  0x2460,  0x2461,  0x2462,  0x2463,  0x2464,  0x2465,  0x2466,  0x2467,
  0x2468,  0x2469,  0x246A,  0x246B,  0x246C,  0x246D,  0x246E,  0x246F,
  0x2470,  0x2471,  0x2472,  0x2473,  0x2474,  0x2475,  0x2476,  0x2477,
  0x2478,  0x2479,  0x247A,  0x247B,  0x247C,  0x247D,  0x247E,  0x247F,
  0x2480,  0x2481,  0x2482,  0x2483,  0x2484,  0x2485,  0x2486,  0x2487,
  0x2488,  0x2489,  0x248A,  0x248B,  0x248C,  0x248D,  0x248E,  0x248F,
  0x2490,  0x2491,  0x2492,  0x2493,  0x2494,  0x2495,  0x2496,  0x2497,
  0x2498,  0x2499,  0x249A,  0x249B,  0x249C,  0x249D,  0x249E,  0x249F,
  0x24A0,  0x24A1,  0x24A2,  0x24A3,  0x24A4,  0x24A5,  0x24A6,  0x24A7,
  0x24A8,  0x24A9,  0x24AA,  0x24AB,  0x24AC,  0x24AD,  0x24AE,  0x24AF,
  0x24B0,  0x24B1,  0x24B2,  0x24B3,  0x24B4,  0x24B5,  0x24B6,  0x24B7,
  0x24B8,  0x24B9,  0x24BA,  0x24BB,  0x24BC,  0x24BD,  0x24BE,  0x24BF,
  0x24C0,  0x24C1,  0x24C2,  0x24C3,  0x24C4,  0x24C5,  0x24C6,  0x24C7,
  0x24C8,  0x24C9,  0x24CA,  0x24CB,  0x24CC,  0x24CD,  0x24CE,  0x24CF,
  0x24B6,  0x24B7,  0x24B8,  0x24B9,  0x24BA,  0x24BB,  0x24BC,  0x24BD,
  0x24BE,  0x24BF,  0x24C0,  0x24C1,  0x24C2,  0x24C3,  0x24C4,  0x24C5,
  0x24C6,  0x24C7,  0x24C8,  0x24C9,  0x24CA,  0x24CB,  0x24CC,  0x24CD,
  0x24CE,  0x24CF,  0x24EA,  0x24EB,  0x24EC,  0x24ED,  0x24EE,  0x24EF,
  0x24F0,  0x24F1,  0x24F2,  0x24F3,  0x24F4,  0x24F5,  0x24F6,  0x24F7,
  0x24F8,  0x24F9,  0x24FA,  0x24FB,  0x24FC,  0x24FD,  0x24FE,  0x24FF,
};

static uint32_t sort24[]={
  0x2400,  0x2401,  0x2402,  0x2403,  0x2404,  0x2405,  0x2406,  0x2407,
  0x2408,  0x2409,  0x240A,  0x240B,  0x240C,  0x240D,  0x240E,  0x240F,
  0x2410,  0x2411,  0x2412,  0x2413,  0x2414,  0x2415,  0x2416,  0x2417,
  0x2418,  0x2419,  0x241A,  0x241B,  0x241C,  0x241D,  0x241E,  0x241F,
  0x2420,  0x2421,  0x2422,  0x2423,  0x2424,  0x2425,  0x2426,  0x2427,
  0x2428,  0x2429,  0x242A,  0x242B,  0x242C,  0x242D,  0x242E,  0x242F,
  0x2430,  0x2431,  0x2432,  0x2433,  0x2434,  0x2435,  0x2436,  0x2437,
  0x2438,  0x2439,  0x243A,  0x243B,  0x243C,  0x243D,  0x243E,  0x243F,
  0x2440,  0x2441,  0x2442,  0x2443,  0x2444,  0x2445,  0x2446,  0x2447,
  0x2448,  0x2449,  0x244A,  0x244B,  0x244C,  0x244D,  0x244E,  0x244F,
  0x2450,  0x2451,  0x2452,  0x2453,  0x2454,  0x2455,  0x2456,  0x2457,
  0x2458,  0x2459,  0x245A,  0x245B,  0x245C,  0x245D,  0x245E,  0x245F,
  0x2460,  0x2461,  0x2462,  0x2463,  0x2464,  0x2465,  0x2466,  0x2467,
  0x2468,  0x2469,  0x246A,  0x246B,  0x246C,  0x246D,  0x246E,  0x246F,
  0x2470,  0x2471,  0x2472,  0x2473,  0x2474,  0x2475,  0x2476,  0x2477,
  0x2478,  0x2479,  0x247A,  0x247B,  0x247C,  0x247D,  0x247E,  0x247F,
  0x2480,  0x2481,  0x2482,  0x2483,  0x2484,  0x2485,  0x2486,  0x2487,
  0x2488,  0x2489,  0x248A,  0x248B,  0x248C,  0x248D,  0x248E,  0x248F,
  0x2490,  0x2491,  0x2492,  0x2493,  0x2494,  0x2495,  0x2496,  0x2497,
  0x2498,  0x2499,  0x249A,  0x249B,  0x249C,  0x249D,  0x249E,  0x249F,
  0x24A0,  0x24A1,  0x24A2,  0x24A3,  0x24A4,  0x24A5,  0x24A6,  0x24A7,
  0x24A8,  0x24A9,  0x24AA,  0x24AB,  0x24AC,  0x24AD,  0x24AE,  0x24AF,
  0x24B0,  0x24B1,  0x24B2,  0x24B3,  0x24B4,  0x24B5,  0x24B6,  0x24B7,
  0x24B8,  0x24B9,  0x24BA,  0x24BB,  0x24BC,  0x24BD,  0x24BE,  0x24BF,
  0x24C0,  0x24C1,  0x24C2,  0x24C3,  0x24C4,  0x24C5,  0x24C6,  0x24C7,
  0x24C8,  0x24C9,  0x24CA,  0x24CB,  0x24CC,  0x24CD,  0x24CE,  0x24CF,
  0x24B6,  0x24B7,  0x24B8,  0x24B9,  0x24BA,  0x24BB,  0x24BC,  0x24BD,
  0x24BE,  0x24BF,  0x24C0,  0x24C1,  0x24C2,  0x24C3,  0x24C4,  0x24C5,
  0x24C6,  0x24C7,  0x24C8,  0x24C9,  0x24CA,  0x24CB,  0x24CC,  0x24CD,
  0x24CE,  0x24CF,  0x24EA,  0x24EB,  0x24EC,  0x24ED,  0x24EE,  0x24EF,
  0x24F0,  0x24F1,  0x24F2,  0x24F3,  0x24F4,  0x24F5,  0x24F6,  0x24F7,
  0x24F8,  0x24F9,  0x24FA,  0x24FB,  0x24FC,  0x24FD,  0x24FE,  0x24FF,
};

static uint32_t lowerFF[]={
  0xFF00,  0xFF01,  0xFF02,  0xFF03,  0xFF04,  0xFF05,  0xFF06,  0xFF07,
  0xFF08,  0xFF09,  0xFF0A,  0xFF0B,  0xFF0C,  0xFF0D,  0xFF0E,  0xFF0F,
  0xFF10,  0xFF11,  0xFF12,  0xFF13,  0xFF14,  0xFF15,  0xFF16,  0xFF17,
  0xFF18,  0xFF19,  0xFF1A,  0xFF1B,  0xFF1C,  0xFF1D,  0xFF1E,  0xFF1F,
  0xFF20,  0xFF41,  0xFF42,  0xFF43,  0xFF44,  0xFF45,  0xFF46,  0xFF47,
  0xFF48,  0xFF49,  0xFF4A,  0xFF4B,  0xFF4C,  0xFF4D,  0xFF4E,  0xFF4F,
  0xFF50,  0xFF51,  0xFF52,  0xFF53,  0xFF54,  0xFF55,  0xFF56,  0xFF57,
  0xFF58,  0xFF59,  0xFF5A,  0xFF3B,  0xFF3C,  0xFF3D,  0xFF3E,  0xFF3F,
  0xFF40,  0xFF41,  0xFF42,  0xFF43,  0xFF44,  0xFF45,  0xFF46,  0xFF47,
  0xFF48,  0xFF49,  0xFF4A,  0xFF4B,  0xFF4C,  0xFF4D,  0xFF4E,  0xFF4F,
  0xFF50,  0xFF51,  0xFF52,  0xFF53,  0xFF54,  0xFF55,  0xFF56,  0xFF57,
  0xFF58,  0xFF59,  0xFF5A,  0xFF5B,  0xFF5C,  0xFF5D,  0xFF5E,  0xFF5F,
  0xFF60,  0xFF61,  0xFF62,  0xFF63,  0xFF64,  0xFF65,  0xFF66,  0xFF67,
  0xFF68,  0xFF69,  0xFF6A,  0xFF6B,  0xFF6C,  0xFF6D,  0xFF6E,  0xFF6F,
  0xFF70,  0xFF71,  0xFF72,  0xFF73,  0xFF74,  0xFF75,  0xFF76,  0xFF77,
  0xFF78,  0xFF79,  0xFF7A,  0xFF7B,  0xFF7C,  0xFF7D,  0xFF7E,  0xFF7F,
  0xFF80,  0xFF81,  0xFF82,  0xFF83,  0xFF84,  0xFF85,  0xFF86,  0xFF87,
  0xFF88,  0xFF89,  0xFF8A,  0xFF8B,  0xFF8C,  0xFF8D,  0xFF8E,  0xFF8F,
  0xFF90,  0xFF91,  0xFF92,  0xFF93,  0xFF94,  0xFF95,  0xFF96,  0xFF97,
  0xFF98,  0xFF99,  0xFF9A,  0xFF9B,  0xFF9C,  0xFF9D,  0xFF9E,  0xFF9F,
  0xFFA0,  0xFFA1,  0xFFA2,  0xFFA3,  0xFFA4,  0xFFA5,  0xFFA6,  0xFFA7,
  0xFFA8,  0xFFA9,  0xFFAA,  0xFFAB,  0xFFAC,  0xFFAD,  0xFFAE,  0xFFAF,
  0xFFB0,  0xFFB1,  0xFFB2,  0xFFB3,  0xFFB4,  0xFFB5,  0xFFB6,  0xFFB7,
  0xFFB8,  0xFFB9,  0xFFBA,  0xFFBB,  0xFFBC,  0xFFBD,  0xFFBE,  0xFFBF,
  0xFFC0,  0xFFC1,  0xFFC2,  0xFFC3,  0xFFC4,  0xFFC5,  0xFFC6,  0xFFC7,
  0xFFC8,  0xFFC9,  0xFFCA,  0xFFCB,  0xFFCC,  0xFFCD,  0xFFCE,  0xFFCF,
  0xFFD0,  0xFFD1,  0xFFD2,  0xFFD3,  0xFFD4,  0xFFD5,  0xFFD6,  0xFFD7,
  0xFFD8,  0xFFD9,  0xFFDA,  0xFFDB,  0xFFDC,  0xFFDD,  0xFFDE,  0xFFDF,
  0xFFE0,  0xFFE1,  0xFFE2,  0xFFE3,  0xFFE4,  0xFFE5,  0xFFE6,  0xFFE7,
  0xFFE8,  0xFFE9,  0xFFEA,  0xFFEB,  0xFFEC,  0xFFED,  0xFFEE,  0xFFEF,
  0xFFF0,  0xFFF1,  0xFFF2,  0xFFF3,  0xFFF4,  0xFFF5,  0xFFF6,  0xFFF7,
  0xFFF8,  0xFFF9,  0xFFFA,  0xFFFB,  0xFFFC,  0xFFFD,  0xFFFE,  0xFFFF,
};

static uint32_t upperFF[]={
  0xFF00,  0xFF01,  0xFF02,  0xFF03,  0xFF04,  0xFF05,  0xFF06,  0xFF07,
  0xFF08,  0xFF09,  0xFF0A,  0xFF0B,  0xFF0C,  0xFF0D,  0xFF0E,  0xFF0F,
  0xFF10,  0xFF11,  0xFF12,  0xFF13,  0xFF14,  0xFF15,  0xFF16,  0xFF17,
  0xFF18,  0xFF19,  0xFF1A,  0xFF1B,  0xFF1C,  0xFF1D,  0xFF1E,  0xFF1F,
  0xFF20,  0xFF21,  0xFF22,  0xFF23,  0xFF24,  0xFF25,  0xFF26,  0xFF27,
  0xFF28,  0xFF29,  0xFF2A,  0xFF2B,  0xFF2C,  0xFF2D,  0xFF2E,  0xFF2F,
  0xFF30,  0xFF31,  0xFF32,  0xFF33,  0xFF34,  0xFF35,  0xFF36,  0xFF37,
  0xFF38,  0xFF39,  0xFF3A,  0xFF3B,  0xFF3C,  0xFF3D,  0xFF3E,  0xFF3F,
  0xFF40,  0xFF21,  0xFF22,  0xFF23,  0xFF24,  0xFF25,  0xFF26,  0xFF27,
  0xFF28,  0xFF29,  0xFF2A,  0xFF2B,  0xFF2C,  0xFF2D,  0xFF2E,  0xFF2F,
  0xFF30,  0xFF31,  0xFF32,  0xFF33,  0xFF34,  0xFF35,  0xFF36,  0xFF37,
  0xFF38,  0xFF39,  0xFF3A,  0xFF5B,  0xFF5C,  0xFF5D,  0xFF5E,  0xFF5F,
  0xFF60,  0xFF61,  0xFF62,  0xFF63,  0xFF64,  0xFF65,  0xFF66,  0xFF67,
  0xFF68,  0xFF69,  0xFF6A,  0xFF6B,  0xFF6C,  0xFF6D,  0xFF6E,  0xFF6F,
  0xFF70,  0xFF71,  0xFF72,  0xFF73,  0xFF74,  0xFF75,  0xFF76,  0xFF77,
  0xFF78,  0xFF79,  0xFF7A,  0xFF7B,  0xFF7C,  0xFF7D,  0xFF7E,  0xFF7F,
  0xFF80,  0xFF81,  0xFF82,  0xFF83,  0xFF84,  0xFF85,  0xFF86,  0xFF87,
  0xFF88,  0xFF89,  0xFF8A,  0xFF8B,  0xFF8C,  0xFF8D,  0xFF8E,  0xFF8F,
  0xFF90,  0xFF91,  0xFF92,  0xFF93,  0xFF94,  0xFF95,  0xFF96,  0xFF97,
  0xFF98,  0xFF99,  0xFF9A,  0xFF9B,  0xFF9C,  0xFF9D,  0xFF9E,  0xFF9F,
  0xFFA0,  0xFFA1,  0xFFA2,  0xFFA3,  0xFFA4,  0xFFA5,  0xFFA6,  0xFFA7,
  0xFFA8,  0xFFA9,  0xFFAA,  0xFFAB,  0xFFAC,  0xFFAD,  0xFFAE,  0xFFAF,
  0xFFB0,  0xFFB1,  0xFFB2,  0xFFB3,  0xFFB4,  0xFFB5,  0xFFB6,  0xFFB7,
  0xFFB8,  0xFFB9,  0xFFBA,  0xFFBB,  0xFFBC,  0xFFBD,  0xFFBE,  0xFFBF,
  0xFFC0,  0xFFC1,  0xFFC2,  0xFFC3,  0xFFC4,  0xFFC5,  0xFFC6,  0xFFC7,
  0xFFC8,  0xFFC9,  0xFFCA,  0xFFCB,  0xFFCC,  0xFFCD,  0xFFCE,  0xFFCF,
  0xFFD0,  0xFFD1,  0xFFD2,  0xFFD3,  0xFFD4,  0xFFD5,  0xFFD6,  0xFFD7,
  0xFFD8,  0xFFD9,  0xFFDA,  0xFFDB,  0xFFDC,  0xFFDD,  0xFFDE,  0xFFDF,
  0xFFE0,  0xFFE1,  0xFFE2,  0xFFE3,  0xFFE4,  0xFFE5,  0xFFE6,  0xFFE7,
  0xFFE8,  0xFFE9,  0xFFEA,  0xFFEB,  0xFFEC,  0xFFED,  0xFFEE,  0xFFEF,
  0xFFF0,  0xFFF1,  0xFFF2,  0xFFF3,  0xFFF4,  0xFFF5,  0xFFF6,  0xFFF7,
  0xFFF8,  0xFFF9,  0xFFFA,  0xFFFB,  0xFFFC,  0xFFFD,  0xFFFE,  0xFFFF,
};

static uint32_t sortFF[]={
  0xFF00,  0xFF01,  0xFF02,  0xFF03,  0xFF04,  0xFF05,  0xFF06,  0xFF07,
  0xFF08,  0xFF09,  0xFF0A,  0xFF0B,  0xFF0C,  0xFF0D,  0xFF0E,  0xFF0F,
  0xFF10,  0xFF11,  0xFF12,  0xFF13,  0xFF14,  0xFF15,  0xFF16,  0xFF17,
  0xFF18,  0xFF19,  0xFF1A,  0xFF1B,  0xFF1C,  0xFF1D,  0xFF1E,  0xFF1F,
  0xFF20,  0xFF21,  0xFF22,  0xFF23,  0xFF24,  0xFF25,  0xFF26,  0xFF27,
  0xFF28,  0xFF29,  0xFF2A,  0xFF2B,  0xFF2C,  0xFF2D,  0xFF2E,  0xFF2F,
  0xFF30,  0xFF31,  0xFF32,  0xFF33,  0xFF34,  0xFF35,  0xFF36,  0xFF37,
  0xFF38,  0xFF39,  0xFF3A,  0xFF3B,  0xFF3C,  0xFF3D,  0xFF3E,  0xFF3F,
  0xFF40,  0xFF21,  0xFF22,  0xFF23,  0xFF24,  0xFF25,  0xFF26,  0xFF27,
  0xFF28,  0xFF29,  0xFF2A,  0xFF2B,  0xFF2C,  0xFF2D,  0xFF2E,  0xFF2F,
  0xFF30,  0xFF31,  0xFF32,  0xFF33,  0xFF34,  0xFF35,  0xFF36,  0xFF37,
  0xFF38,  0xFF39,  0xFF3A,  0xFF5B,  0xFF5C,  0xFF5D,  0xFF5E,  0xFF5F,
  0xFF60,  0xFF61,  0xFF62,  0xFF63,  0xFF64,  0xFF65,  0xFF66,  0xFF67,
  0xFF68,  0xFF69,  0xFF6A,  0xFF6B,  0xFF6C,  0xFF6D,  0xFF6E,  0xFF6F,
  0xFF70,  0xFF71,  0xFF72,  0xFF73,  0xFF74,  0xFF75,  0xFF76,  0xFF77,
  0xFF78,  0xFF79,  0xFF7A,  0xFF7B,  0xFF7C,  0xFF7D,  0xFF7E,  0xFF7F,
  0xFF80,  0xFF81,  0xFF82,  0xFF83,  0xFF84,  0xFF85,  0xFF86,  0xFF87,
  0xFF88,  0xFF89,  0xFF8A,  0xFF8B,  0xFF8C,  0xFF8D,  0xFF8E,  0xFF8F,
  0xFF90,  0xFF91,  0xFF92,  0xFF93,  0xFF94,  0xFF95,  0xFF96,  0xFF97,
  0xFF98,  0xFF99,  0xFF9A,  0xFF9B,  0xFF9C,  0xFF9D,  0xFF9E,  0xFF9F,
  0xFFA0,  0xFFA1,  0xFFA2,  0xFFA3,  0xFFA4,  0xFFA5,  0xFFA6,  0xFFA7,
  0xFFA8,  0xFFA9,  0xFFAA,  0xFFAB,  0xFFAC,  0xFFAD,  0xFFAE,  0xFFAF,
  0xFFB0,  0xFFB1,  0xFFB2,  0xFFB3,  0xFFB4,  0xFFB5,  0xFFB6,  0xFFB7,
  0xFFB8,  0xFFB9,  0xFFBA,  0xFFBB,  0xFFBC,  0xFFBD,  0xFFBE,  0xFFBF,
  0xFFC0,  0xFFC1,  0xFFC2,  0xFFC3,  0xFFC4,  0xFFC5,  0xFFC6,  0xFFC7,
  0xFFC8,  0xFFC9,  0xFFCA,  0xFFCB,  0xFFCC,  0xFFCD,  0xFFCE,  0xFFCF,
  0xFFD0,  0xFFD1,  0xFFD2,  0xFFD3,  0xFFD4,  0xFFD5,  0xFFD6,  0xFFD7,
  0xFFD8,  0xFFD9,  0xFFDA,  0xFFDB,  0xFFDC,  0xFFDD,  0xFFDE,  0xFFDF,
  0xFFE0,  0xFFE1,  0xFFE2,  0xFFE3,  0xFFE4,  0xFFE5,  0xFFE6,  0xFFE7,
  0xFFE8,  0xFFE9,  0xFFEA,  0xFFEB,  0xFFEC,  0xFFED,  0xFFEE,  0xFFEF,
  0xFFF0,  0xFFF1,  0xFFF2,  0xFFF3,  0xFFF4,  0xFFF5,  0xFFF6,  0xFFF7,
  0xFFF8,  0xFFF9,  0xFFFA,  0xFFFB,  0xFFFC,  0xFFFD,  0xFFFE,  0xFFFF,
};

static uint32_t *ob_toupper_pages_utf8[256]=
{
    upper00, upper01, upper02, upper03, upper04, upper05, NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    upper1E, upper1F,
    NULL,    upper21, NULL,    NULL,    upper24, NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    upperFF,
};

static uint32_t *ob_tolower_pages_utf8[256]=
{
    lower00, lower01, lower02, lower03, lower04, lower05, NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    lower1E, lower1F,
    NULL,    lower21, NULL,    NULL,    lower24, NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,   lowerFF,
};

static uint32_t *ob_sort_pages_utf8[256]=
{
    sort00,  sort01,  sort02,  sort03,  sort04,  sort05,  NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,   sort1E,   sort1F,
    NULL,    sort21,  NULL,    NULL,    sort24,  NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    sortFF,
};

ObUnicasePages utf8_unicase_pages = {
  ob_toupper_pages_utf8,
  ob_tolower_pages_utf8,
  ob_sort_pages_utf8,
};


//==========================================================================

static int ob_valid_mbcharlen_utf8mb4(const unsigned char *str, size_t len)
{
  int ret = 0;

  if (OB_UNLIKELY(len <= 0)) {
    ret = OB_CS_ERR_TOOSMALL;
  } else if (str[0] < 0x80) {
    ret = 1;
  } else if (str[0] < 0xE0) {
    if (OB_UNLIKELY(len < 2)) {
      ret = OB_CS_ERR_TOOSMALL2;
    } else if (OB_UNLIKELY(!(IS_CONTINUATION_BYTE(str[1])
                             && str[0] >= 0xC2))) {
      ret = OB_CS_ERR_ILLEGAL_SEQUENCE;
    } else {
      ret = 2;
    }
  } else if (str[0] < 0xF0) {
    if (OB_UNLIKELY(len < 3)) {
      ret = OB_CS_ERR_TOOSMALL3;
    } else if (OB_UNLIKELY(!(IS_CONTINUATION_BYTE(str[1])
                             && IS_CONTINUATION_BYTE(str[2])
                             && (str[0] >= 0xE1 || str[1] >= 0xA0)))) {
      ret = OB_CS_ERR_ILLEGAL_SEQUENCE;
    } else {
      ret = 3;
    }
  } else if (str[0] < 0xF5) {
    if (OB_UNLIKELY(len < 4)) {
      ret = OB_CS_ERR_TOOSMALL4;
    } else if (OB_UNLIKELY(!(IS_CONTINUATION_BYTE(str[1])
                             && IS_CONTINUATION_BYTE(str[2])
                             && IS_CONTINUATION_BYTE(str[3])
                             && (str[0] >= 0xF1 || str[1] >= 0x90)
                             && (str[0] <= 0xF3 || str[1] <= 0x8F)))) {
      ret = OB_CS_ERR_ILLEGAL_SEQUENCE;
    } else {
      ret = 4;
    }
  } else {
    ret = OB_CS_ERR_ILLEGAL_SEQUENCE;
  }

  return ret;
}

static uint32_t ob_ismbchar_utf8mb4(const char *str, size_t len)
{
  int res = ob_valid_mbcharlen_utf8mb4((const unsigned char*)str, len);
  return (res > 1) ? res : 0;
}

static size_t ob_well_formed_len_utf8mb4(const char *str, size_t len,
                                          size_t nchars, int *error)
{
  const char *str_begin= str;
  *error = 0;
  for (; nchars > 0 && len > 0; nchars--) {
    int mb_char_len = 0;
    if ((mb_char_len= ob_valid_mbcharlen_utf8mb4((unsigned char*) str, len)) < 0) {
      *error= mb_char_len;
      break;
    }
    str += mb_char_len;
    len -= mb_char_len;
  }
  return (size_t) (str - str_begin);
}

static int ob_mb_wc_utf8mb4(const unsigned char *str, const unsigned char *end, ob_wc_t* wchar)
{
  int ret = OB_CS_SUCCESS;
  int bytes = 0;
  size_t len = (size_t)(end - str);
  if (OB_UNLIKELY(len <= 0)) {
    ret = OB_CS_ERR_TOOSMALL;
  } else if (str[0] < 0x80) {
    *wchar = str[0];
    bytes = 1;
  } else if (OB_UNLIKELY(str[0] < 0xC2)) {
    ret = OB_CS_ERR_ILLEGAL_SEQUENCE;
  } else if (str[0] < 0xE0) {
    if (OB_UNLIKELY(len < 2)) {
      ret = OB_CS_ERR_TOOSMALL2;
    } else if (OB_UNLIKELY(!(IS_CONTINUATION_BYTE(str[1])))) {
      ret = OB_CS_ERR_ILLEGAL_SEQUENCE;
    } else {
      *wchar = ((ob_wc_t) (str[0] & 0x1F) << 6)
          | (ob_wc_t) (str[1] ^ 0x80);
      bytes = 2;
    }
  } else if (str[0] < 0xF0) {
    if (OB_UNLIKELY(len < 3)) {
      ret = OB_CS_ERR_TOOSMALL3;
    } else if (OB_UNLIKELY(!(IS_CONTINUATION_BYTE(str[1])
                             && IS_CONTINUATION_BYTE(str[2])
                             && (str[0] >= 0xE1 || str[1] >= 0xA0)))) {
      ret = OB_CS_ERR_ILLEGAL_SEQUENCE;
    } else {
      *wchar = ((ob_wc_t) (str[0] & 0x0f) << 12)
          | ((ob_wc_t) (str[1] ^ 0x80) << 6)
          | (ob_wc_t) (str[2] ^ 0x80);
      bytes = 3;
    }
  } else if (str[0] < 0xF5) {
    if (OB_UNLIKELY(len < 4)) {
      ret = OB_CS_ERR_TOOSMALL4;
    } else if (OB_UNLIKELY(!(IS_CONTINUATION_BYTE(str[1]) &&
                             IS_CONTINUATION_BYTE(str[2]) &&
                             IS_CONTINUATION_BYTE(str[3]) &&
                             (str[0] >= 0xF1 || str[1] >= 0x90) &&
                             (str[0] <= 0xF3 || str[1] <= 0x8F)))) {
      ret = OB_CS_ERR_ILLEGAL_SEQUENCE;
    } else {
      *wchar= ((ob_wc_t) (str[0] & 0x07) << 18)
          | ((ob_wc_t) (str[1] ^ 0x80) << 12)
          | ((ob_wc_t) (str[2] ^ 0x80) << 6)
          | (ob_wc_t) (str[3] ^ 0x80);
    }
    bytes = 4;
  } else {
    ret = OB_CS_ERR_ILLEGAL_SEQUENCE;
  }
  return OB_CS_SUCC(ret) ? bytes : ret;
}

static int ob_wc_mb_utf8mb4(ob_wc_t wchar, unsigned char *str, unsigned char *end)
{
  int bytes = 0;
  int ret = 0;
  int64_t len = (int64_t)(end - str);
  if (OB_UNLIKELY(len <= 0)) {
    ret = OB_CS_ERR_TOOSMALL;
  } else if (wchar < 0x80) {
    bytes = 1;
  } else if (wchar < 0x800) {
    bytes = 2;
  } else if (wchar < 0x10000) {
    bytes = 3;
  } else if (wchar < 0x200000) {
    bytes = 4;
  } else {
    ret = OB_CS_ERR_ILLEGAL_UNICODE;
  }
  if (OB_UNLIKELY(bytes > len)) {
    ret = OB_CS_ERR_TOOSMALLN(bytes);
  } else {
    switch (bytes) {
      case 4:
        str[3] = (unsigned char) (0x80 | (wchar & 0x3F));
        wchar = (wchar >> 6) | 0x10000;
      case 3:
        str[2] = (unsigned char) (0x80 | (wchar & 0x3F));
        wchar = (wchar >> 6) | 0x800;
      case 2:
        str[1] = (unsigned char) (0x80 | (wchar & 0x3F));
        wchar = (wchar >> 6) | 0xC0;
      case 1:
        str[0] = (unsigned char) wchar;
    }
  }

  return OB_CS_SUCC(ret) ? bytes : ret;
}

static inline void ob_page_help_utf8mb4(uint32_t **plane, ob_wc_t *wchar)
{
  if (*wchar <= 0xFFFF) {
    uint32_t *page = plane[(*wchar >> 8)];
    if (OB_NOT_NULL(page)) {
      *wchar= page[*wchar & 0xFF];
    }
  }
}

static inline void ob_tolower_utf8mb4(uint32_t **lower_plane, ob_wc_t *wchar)
{
  ob_page_help_utf8mb4(lower_plane, wchar);
}


static inline void ob_toupper_utf8mb4(uint32_t **upper_plane, ob_wc_t *wchar)
{
  ob_page_help_utf8mb4(upper_plane, wchar);
}


static size_t ob_caseup_utf8mb4(const ObCharsetInfo *cs,
                                 char *src, size_t srclen,
                                 char *dst, size_t dstlen)
{
  int ret = OB_CS_SUCCESS;
  ob_wc_t wchar;
  int srcres = 0;
  int dstres = 0;
  char *srcend= src + srclen;
  char *dstend= dst + dstlen;
  char *dstbegin = dst;
  uint32_t **upper_pages= cs->caseinfo->upper_pages;
  while (src < srcend && dst < dstend) {
    if (OB_LIKELY((srcres = ob_mb_wc_utf8mb4((unsigned char *) src,
                                             (unsigned char*) srcend, &wchar)) > 0)) {
      ob_toupper_utf8mb4(upper_pages, &wchar);
      if (OB_UNLIKELY((dstres = ob_wc_mb_utf8mb4(wchar, (unsigned char*) dst,
                                                 (unsigned char*) dstend)) <= 0)) {
        ret = OB_CS_ERR_ILLEGAL_UNICODE;
        break;
      }
    } else {
      *dst = *src;
      srcres = 1;
      dstres = 1;
    }
    src+= srcres;
    dst+= dstres;
  }
  return OB_CS_SUCC(ret) ? (size_t) (dst - dstbegin) : ret;
}

static size_t ob_casedn_utf8mb4(const ObCharsetInfo *cs,
                                 char *src, size_t srclen,
                                 char *dst, size_t dstlen)
{
  int ret = OB_CS_SUCCESS;
  ob_wc_t wchar;
  int srcres = 0;
  int dstres = 0;
  char *srcend= src + srclen;
  char *dstend= dst + dstlen;
  char *dstbegin = dst;
  uint32_t **lower_pages= cs->caseinfo->lower_pages;
  while (src < srcend && dst < dstend) {
    if (OB_LIKELY((srcres = ob_mb_wc_utf8mb4((unsigned char *) src,
                                             (unsigned char*) srcend, &wchar)) > 0)) {
      ob_tolower_utf8mb4(lower_pages, &wchar);
      if (OB_UNLIKELY((dstres = ob_wc_mb_utf8mb4(wchar, (unsigned char*) dst,
                                                 (unsigned char*) dstend)) <= 0)) {
        ret = OB_CS_ERR_ILLEGAL_UNICODE;
        break;
      }
    } else {
      *dst = *src;
      srcres = 1;
      dstres = 1;
    }
    src+= srcres;
    dst+= dstres;
  }
  return OB_CS_SUCC(ret) ? (size_t) (dst - dstbegin) : ret;
}


static inline int bincmp_utf8mb4(const unsigned char *src, size_t src_len,
                                 const unsigned char *dst, size_t dst_len)
{
  int min_len= src_len < dst_len ? src_len : dst_len;
  int cmp= memcmp(src, dst, min_len);
  return !!(cmp) ? cmp : src_len - dst_len;
}

static inline void ob_tosort_unicode(uint32_t **sort_plane, ob_wc_t *wchar)
{
  if (*wchar <= 0xFFFF) {
    uint32_t *page = sort_plane[*wchar >> 8];
    if (OB_NOT_NULL(page)) {
      *wchar= page[*wchar & 0xFF];
    }
  } else {
    *wchar = OB_CS_REPLACEMENT_CHARACTER;
  }
}

static int ob_strnncoll_utf8mb4(const ObCharsetInfo *cs,
                                const unsigned char *src, size_t src_len,
                                const unsigned char *dst, size_t dst_len)
{
  ob_wc_t src_wchar = 0;
  ob_wc_t dst_wchar = 0;
  const unsigned char *src_end = src + src_len;
  const unsigned char *dst_end = dst + dst_len;
  uint32_t **sort_pages = cs->caseinfo->sort_pages;
  while (src < src_end && dst < dst_end) {
    int src_res = ob_mb_wc_utf8mb4(src, src_end, &src_wchar);
    int dst_res = ob_mb_wc_utf8mb4(dst, dst_end, &dst_wchar);
    if (src_res <= 0 || dst_res <= 0) {
      /* Incorrect string, compare bytewise */
      return bincmp_utf8mb4(src, src_end-src, dst, dst_end-dst);
    }
    ob_tosort_unicode(sort_pages, &src_wchar);
    ob_tosort_unicode(sort_pages, &dst_wchar);
    if (src_wchar != dst_wchar) {
      return src_wchar > dst_wchar ? 1 : -1;
    }
    src+= src_res;
    dst+= dst_res;
  }
  return (int) ((src_end - src) - (dst_end - dst));
}

static int ob_strnncollsp_utf8mb4(const ObCharsetInfo *cs,
                                  const unsigned char *src, size_t src_len,
                                  const unsigned char *dst, size_t dst_len)
{
  int res = 0;
  ob_wc_t src_wchar = 0;
  ob_wc_t dst_wchar = 0;
  const unsigned char *src_end = src + src_len;
  const unsigned char *dst_end = dst + dst_len;
  uint32_t **sort_pages = cs->caseinfo->sort_pages;
  while (src < src_end && dst < dst_end) {
    int src_res = ob_mb_wc_utf8mb4(src, src_end, &src_wchar);
    int dst_res = ob_mb_wc_utf8mb4(dst, dst_end, &dst_wchar);
    if (src_res <= 0 || dst_res <= 0) {
      /* Incorrect string, compare bytewise */
      return bincmp_utf8mb4(src, src_end-src, dst, dst_end-dst);
    }
    ob_tosort_unicode(sort_pages, &src_wchar);
    ob_tosort_unicode(sort_pages, &dst_wchar);
    if (src_wchar != dst_wchar) {
      return src_wchar > dst_wchar ? 1 : -1;
    }
    src+= src_res;
    dst+= dst_res;
  }
  src_len= (size_t) (src_end - src);
  dst_len= (size_t) (dst_end - dst);
  if (src_len != dst_len) {
    int swap = 1;
    if (src_len < dst_len) {
      src_len = dst_len;
      src = dst;
      src_end = dst_end;
      swap = -1;
      res = -res;
    }
    for (; src < src_end; src++) {
      if (*src != ' ') return (*src < ' ') ? -swap : swap;
    }
  }
  return res;
}

size_t ob_strnxfrm_unicode(const ObCharsetInfo *cs,
                            unsigned char *dst, size_t dst_len, uint32_t nweights,
                            const unsigned char *src, size_t src_len, int *is_valid_unicode)
{
  ob_wc_t wchar = 0;
  int cur_len = 0;
  unsigned char *dst_begin= dst;
  unsigned char *dst_end= dst + dst_len;
  const unsigned char *src_end= src + src_len;
  uint32_t **sort_pages= (cs->state & OB_CS_BINSORT) ? NULL : cs->caseinfo->sort_pages;
  *is_valid_unicode = 1;

  for (; dst < dst_end && nweights; nweights--) {
    if ((cur_len = cs->cset->mb_wc(src, src_end, &wchar)) <= 0) {
      if (src < src_end) {
        *is_valid_unicode = 0;
      }
      break;
    }
    src += cur_len;
    if (sort_pages) {
      ob_tosort_unicode(sort_pages, &wchar);
    }
    if ((cur_len = cs->cset->wc_mb(wchar, dst, dst_end)) <= 0) {
      break;
    }
    dst += cur_len;
  }
  //ob_strnxfrm_unicode_help(&dst, &dst_end, nweights, &dst0);
  return dst - dst_begin;
}

//==============================================================

static int ob_wildcmp_unicode_impl(const ObCharsetInfo *cs,
                        const char *str,const char *str_end,
                        const char *wildstr,const char *wildend,
                        int escape, int w_one, int w_many,
                        uint32_t **weights, int recurse_level)
{
  int result= -1;                             /* Not found, using wildcards */
  ob_wc_t s_wc = 0;
  ob_wc_t w_wc = 0;
  int scan_len = 0;
  ob_charset_conv_mb_wc mb_wc = cs->cset->mb_wc;

 /*if (ob_string_stack_guard && ob_string_stack_guard(recurse_level))
   return 1;*/
  while (wildstr != wildend) {
    while (1)
    {
      int escaped= 0;
      if ((scan_len = mb_wc((const unsigned char*)wildstr,
                            (const unsigned char*)wildend, &w_wc)) <= 0) {
        return 1;
      }
      if (w_wc == (uint32_t) w_many) {
        result = 1;                               /* Found an anchor char */
        break;
      }
      wildstr += scan_len;

      if (w_wc ==  (uint32_t) escape && wildstr < wildend) {
        if ((scan_len = mb_wc((const unsigned char*)wildstr,
                              (const unsigned char*)wildend, &w_wc)) <= 0) {
          return 1;
        }
        wildstr += scan_len;
        escaped = 1;
      }

      if ((scan_len = mb_wc((const unsigned char*)str,
                            (const unsigned char*)str_end, &s_wc)) <= 0) {
        return 1;
      }
      str += scan_len;

      if (!escaped && w_wc == (uint32_t) w_one) {
        result = 1;                                /* Found an anchor char */
      } else {
        if (weights) {
          ob_tosort_unicode(weights, &s_wc);
          ob_tosort_unicode(weights, &w_wc);
        }
        if (s_wc != w_wc) {
          return 1;                                 /* No match */
        }
      }
      if (wildstr == wildend) {
        return (str != str_end);                    /* Match if both are at end */
      }
    }

    if (w_wc == (uint32_t) w_many) {                /* Found w_many */
      /* Remove any '%' and '_' from the wild search string */
      for ( ; wildstr != wildend ; ) {
        if ((scan_len = mb_wc((const unsigned char*)wildstr,
                              (const unsigned char*)wildend, &w_wc)) <= 0) {
          return 1;
        }

        if (w_wc == (uint32_t)w_many) {
          wildstr+= scan_len;
          continue;
        }

        if (w_wc == (uint32_t)w_one) {
          wildstr+= scan_len;
          if ((scan_len = mb_wc((const unsigned char*)str,
                                (const unsigned char*)str_end, &s_wc)) <= 0) {
            return 1;
          }
          str+= scan_len;
          continue;
        }
        break;                                        /* Not a wild character */
      }

      if (wildstr == wildend) {
        return 0;                                /* Ok if w_many is last */
      }

      if (str == str_end) {
        return -1;
      }

      if ((scan_len = mb_wc((const unsigned char*)wildstr,
                            (const unsigned char*)wildend, &w_wc)) <= 0) {
        return 1;
      }
      wildstr+= scan_len;

      if (w_wc ==  (uint32_t)escape) {
        if (wildstr < wildend) {
          if ((scan_len = mb_wc((const unsigned char*)wildstr,
                                (const unsigned char*)wildend, &w_wc)) <= 0) {
            return 1;
          }
          wildstr+= scan_len;
        }
      }

      /* Skip until the first character from wildstr is found */
      while (1) {
        while (str != str_end) {
          if ((scan_len = mb_wc((const unsigned char*)str,
                                (const unsigned char*)str_end, &s_wc)) <= 0) {
            return 1;
          }
          if (weights) {
            ob_tosort_unicode(weights, &s_wc);
            ob_tosort_unicode(weights, &w_wc);
          }

          if (s_wc == w_wc) {
            break;
          }
          str+= scan_len;
        }
        if (str == str_end) {
          return -1;
        }

        str+= scan_len;
        result = ob_wildcmp_unicode_impl(cs, str, str_end, wildstr, wildend,
                                         escape, w_one, w_many,
                                         weights, recurse_level + 1);
        if (result <= 0)
          return result;
      }
    }
  }
  return (str != str_end ? 1 : 0);
}

int ob_wildcmp_unicode(const ObCharsetInfo *cs,
                   const char *str,const char *str_end,
                   const char *wildstr,const char *wildend,
                   int escape, int w_one, int w_many,
                   uint32_t **weights)
{
  return ob_wildcmp_unicode_impl(cs, str, str_end, wildstr, wildend, escape, w_one, w_many, weights, 1);
}

static int ob_wildcmp_utf8mb4(const ObCharsetInfo *cs,
                              const char *str, const char *strend,
                              const char *wildstr, const char *wildend,
                              int escape, int w_one, int w_many)
{
  return ob_wildcmp_unicode(cs, str, strend, wildstr, wildend, escape, w_one, w_many,
                            cs->caseinfo->sort_pages);
}

//======================================================================

static inline void ob_hash_add(uint64_t *n1, uint64_t *n2, uint32_t ch)
{
  n1[0]^= (((n1[0] & 63) + n2[0]) * (ch)) + (n1[0] << 8);
  n2[0]+= 3;
}


static void ob_hash_sort_utf8mb4(const ObCharsetInfo *cs, const unsigned char *s, size_t slen,
                                 uint64_t *n1, uint64_t *n2,
                                 const int calc_end_space, hash_algo hash_algo)
{
  ob_wc_t wc;
  int res;
  const unsigned char *e= s + slen;
  uint32_t **sort_pages= cs->caseinfo->sort_pages;
  int length = 0;
  unsigned char data[HASH_BUFFER_LENGTH];
  /*
    Remove trailing spaces if calc_end_space is false: for char(Oracle/MySql mode) or Varchar(MySql mode).
    We do this to be able to compare 'A ' and 'A' as identical
  */
  if (!calc_end_space) {
    while (e > s && e[-1] == ' ') {
      e--;
    }
  }

  if (NULL == hash_algo) {
    while ((res= ob_mb_wc_utf8mb4((unsigned char*) s, (unsigned char*) e, &wc)) > 0) {
      ob_tosort_unicode(sort_pages, &wc);
      ob_hash_add(n1, n2, (uint32_t) (wc & 0xFF));
      ob_hash_add(n1, n2, (uint32_t) (wc >> 8)  & 0xFF);
      if (wc > 0xFFFF) {
        ob_hash_add(n1, n2, (uint32_t) (wc >> 16) & 0xFF);
      }
      s+= res;
    }
  } else {
    while ((res= ob_mb_wc_utf8mb4((unsigned char*) s, (unsigned char*) e, &wc)) > 0) {
      ob_tosort_unicode(sort_pages, &wc);
      if (length > HASH_BUFFER_LENGTH - 2 || (HASH_BUFFER_LENGTH - 2 == length && wc > 0xFFFF)) {
        *n1 = hash_algo((void*) &data, length, *n1);
        length = 0;
      }
      data[length++] = (unsigned char)wc;
      data[length++] = (unsigned char)(wc >> 8);
      if (wc > 0xFFFF) {
        data[length++] = (unsigned char)(wc >> 16);
      }
      s+= res;
    }
    if (length > 0) {
      *n1 = hash_algo((void*) &data, length, *n1);
    }
  }
}

//======================================================================

size_t ob_strnxfrm_unicode_full_bin(const ObCharsetInfo *cs,
                                     unsigned char *dst, size_t dstlen, uint32_t nweights,
                                     const unsigned char *src, size_t srclen,
                                     int *is_valid_unicode)
{
  ob_wc_t wc;
  unsigned char *dst0= dst;
  unsigned char *de= dst + dstlen;
  const unsigned char *se = src + srclen;
  wc = 0;
  ob_charset_assert(src);
  ob_charset_assert(cs->state & OB_CS_BINSORT);
  *is_valid_unicode = 1;
  for ( ; dst < de && nweights; nweights--) {
    int res;
    if ((res= cs->cset->mb_wc(src, se, &wc)) <= 0) {
      if (src < se) {
        *is_valid_unicode = 0;
      }
      break;
    }
    src+= res;
    if ((res= cs->cset->wc_mb(wc, dst, de)) <= 0) {
      break;
    }
    dst+= res;
  }

  return dst - dst0;
}

//======================================================================

ObCharsetHandler ob_charset_utf8mb4_handler=
{
  ob_ismbchar_utf8mb4,
  ob_numchars_mb,
  ob_charpos_mb,
  ob_max_bytes_charpos_mb,
  ob_well_formed_len_utf8mb4,
  ob_lengthsp_8bit,
  ob_mb_wc_utf8mb4,
  ob_wc_mb_utf8mb4,
  ob_mb_ctype_mb,
  ob_caseup_utf8mb4,
  ob_casedn_utf8mb4,
  ob_fill_8bit,
  ob_strntoll_8bit,
  ob_strntoull_8bit,
  ob_strntod_8bit,
  ob_strntoull10rnd_8bit,
  ob_scan_8bit
};

static ObCollationHandler ob_collation_utf8mb4_general_ci_handler=
{
  ob_strnncoll_utf8mb4,
  ob_strnncollsp_utf8mb4,
  ob_strnxfrm_unicode,
  ob_like_range_mb,
  ob_wildcmp_utf8mb4,
  ob_instr_mb,
  ob_hash_sort_utf8mb4,
};

static ObCollationHandler ob_collation_utf8mb4_bin_handler =
{
  ob_strnncoll_mb_bin,
  ob_strnncollsp_mb_bin,
  ob_strnxfrm_unicode_full_bin,
  ob_like_range_mb,
  ob_wildcmp_mb_bin,
  ob_instr_mb,
  ob_hash_sort_mb_bin,
};

ObCharsetInfo ob_charset_utf8mb4_general_ci=
{
  45,0,0,              /* number       */
  OB_CS_COMPILED|OB_CS_PRIMARY|OB_CS_STRNXFRM|OB_CS_UNICODE|OB_CS_UNICODE_SUPPLEMENT,  /* state  */
  OB_UTF8MB4,         /* cs name      */
  OB_UTF8MB4_GENERAL_CI,/* name       */
  "UTF-8 Unicode",    /* comment      */
  NULL,               /* tailoring    */
  ctype_utf8mb4,      /* ctype        */
  to_lower_utf8mb4,   /* to_lower     */
  to_upper_utf8mb4,   /* to_upper     */
  to_upper_utf8mb4,   /* sort_order   */
  &utf8_unicase_pages,/* caseinfo     */
  NULL,               /* state_map    */
  NULL,               /* ident_map    */
  1,                  /* strxfrm_multiply */
  1,                  /* caseup_multiply  */
  1,                  /* casedn_multiply  */
  1,                  /* mbminlen     */
  4,                  /* mbmaxlen     */
  0,                  /* min_sort_char */
  0xFFFF,             /* max_sort_char */
  ' ',                /* pad char      */
  0,                  /* escape_with_backslash_is_dangerous */
  1,                  /* levels_for_compare */
  1,                  /* levels_for_order   */
  &ob_charset_utf8mb4_handler,
  &ob_collation_utf8mb4_general_ci_handler
};

ObCharsetInfo ob_charset_utf8mb4_bin=
{
  46,0,0,             /* number       */
  OB_CS_COMPILED|OB_CS_BINSORT|OB_CS_STRNXFRM|
  OB_CS_UNICODE|OB_CS_UNICODE_SUPPLEMENT, /* state  */
  OB_UTF8MB4,         /* cs name      */
  OB_UTF8MB4_BIN,     /* name         */
  "UTF-8 Unicode",    /* comment      */
  NULL,               /* tailoring    */
  ctype_utf8mb4,      /* ctype        */
  to_lower_utf8mb4,   /* to_lower     */
  to_upper_utf8mb4,   /* to_upper     */
  NULL,               /* sort_order   */
  &utf8_unicase_pages,/* caseinfo     */
  NULL,               /* state_map    */
  NULL,               /* ident_map    */
  1,                  /* strxfrm_multiply */
  1,                  /* caseup_multiply  */
  1,                  /* casedn_multiply  */
  1,                  /* mbminlen     */
  4,                  /* mbmaxlen     */
  0,                  /* min_sort_char */
  0xFFFF,             /* max_sort_char */
  ' ',                /* pad char      */
  0,                  /* escape_with_backslash_is_dangerous */
  1,                  /* levels_for_compare */
  1,                  /* levels_for_order   */
  &ob_charset_utf8mb4_handler,
  &ob_collation_utf8mb4_bin_handler
};

